2014-03-05 149 views
3

我试图在Android应用程序中加密一个字符串,然后在ASP.Net服务器中解密它。我没有收到任何错误,但解密不会返回真正的结果。这里就是Android侧:AES解密给出错误结果

public void clckBtn(View v) { 
     try { 
      SecretKeySpec skeySpec = new SecretKeySpec(
        "MyDifficultPassw".getBytes(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
      byte[] encrypted = cipher.doFinal("tryToEncrypt".getBytes()); 
      System.out.println(toHex(encrypted)); 

     } catch (Exception e) { 
      System.out.println(e.toString()); 
     } 

    } 


    public static String toHex(byte[] buf) { 
     if (buf == null) 
      return ""; 
     StringBuffer result = new StringBuffer(2 * buf.length); 
     for (int i = 0; i < buf.length; i++) { 
      appendHex(result, buf[i]); 
     } 
     return result.toString(); 
    } 

    private final static String HEX = "ABCDEF"; 

    private static void appendHex(StringBuffer sb, byte b) { 
     sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); 
    } 

的输出是:CE3E99F50E6D30201E38D4955F07BA7C

Asp.Net侧:

protected void Page_Load(object sender, EventArgs e) 
     { 
      using (Aes myAes = Aes.Create()) 
      { 
       string asd = DecryptStringFromBytes_Aes(GetBytes("CE3E99F50E6D30201E38D4955F07BA7C"), GetBytes("MyDifficultPassw"), myAes.IV); 
       int we = 0; 
      } 

     } 

     static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key 
, byte[] IV) 
     { 
      // Check arguments. 
      if (cipherText == null || cipherText.Length <= 0) 
       throw new ArgumentNullException("cipherText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("Key"); 

      // Declare the string used to hold 
      // the decrypted text. 
      string plaintext = null; 

      // Create an Aes object 
      // with the specified key and IV. 
      using (Aes aesAlg = Aes.Create()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 
       aesAlg.Padding = PaddingMode.None; 

       // Create a decrytor to perform the stream transform. 
       ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key 
, aesAlg.IV); 



       // Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 

        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt 
, decryptor, CryptoStreamMode.Read)) 
        { 

         using (StreamReader srDecrypt = new StreamReader(
csDecrypt)) 
         { 

          // Read the decrypted bytes from the decrypting 

          // and place them in a string. 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 

      } 

      return plaintext; 

     } 

     static byte[] GetBytes(string str) 
     { 
      byte[] bytes = new byte[str.Length * sizeof(char)]; 
      System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); 
      return bytes; 
     } 

在Asp.Net AES类需要一个IV(初始化矢量)。在Android中没有这样的事情。我认为这个问题是有关于此的。

+0

基本上,你需要确保这些匹配:键,IV,填充,模式。我没有编程Android,但在谷歌上的快速搜索指向我[这](http://stackoverflow.com/a/16854800/706456)。也许你可以从那里获得解决方案。 – oleksii

+1

您在.NET代码中使用Java代码和CBC模式使用ECB模式。另外,我怀疑这段代码实际上并没有完成你所要做的([相关问题])(http://security.stackexchange.com/questions/52584/why-can-we-still-crack-sriest-photos-在-12-线-的旁注))。也许[TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security)更合适? – ntoskrnl

回答

0

我不完全确定我的代码出了什么问题。也许@ntoskrnl是对的。尽管如此,我遵循了一个例子,它的工作。我遵循的是There is the code。我也在这里给出完整的代码。如果有人需要它:

Java方面:

import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

import android.util.Base64; 
import android.util.Log; 

public class Crypto { 
    public static final String TAG = "smsfwd"; 

     private static Cipher aesCipher; 
     private static SecretKey secretKey; 
     private static IvParameterSpec ivParameterSpec; 

     private static String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding"; 
     private static String CIPHER_ALGORITHM = "AES"; 
     // Replace me with a 16-byte key, share between Java and C# 
     private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 

     private static String MESSAGEDIGEST_ALGORITHM = "MD5"; 

     public Crypto(String passphrase) { 
      byte[] passwordKey = encodeDigest(passphrase); 

      try { 
       aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION); 
      } catch (NoSuchAlgorithmException e) { 
       Log.e(TAG, "No such algorithm " + CIPHER_ALGORITHM, e); 
      } catch (NoSuchPaddingException e) { 
       Log.e(TAG, "No such padding PKCS5", e); 
      } 

      secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM); 
      ivParameterSpec = new IvParameterSpec(rawSecretKey); 
     } 

     public String encryptAsBase64(byte[] clearData) { 
      byte[] encryptedData = encrypt(clearData); 
      return Base64.encodeToString(encryptedData, Base64.DEFAULT); 
     } 

     public byte[] encrypt(byte[] clearData) { 
      try { 
       aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); 
      } catch (InvalidKeyException e) { 
       Log.e(TAG, "Invalid key", e); 
       return null; 
      } catch (InvalidAlgorithmParameterException e) { 
       Log.e(TAG, "Invalid algorithm " + CIPHER_ALGORITHM, e); 
       return null; 
      } 

      byte[] encryptedData; 
      try { 
       encryptedData = aesCipher.doFinal(clearData); 
      } catch (IllegalBlockSizeException e) { 
       Log.e(TAG, "Illegal block size", e); 
       return null; 
      } catch (BadPaddingException e) { 
       Log.e(TAG, "Bad padding", e); 
       return null; 
      } 
      return encryptedData; 
     } 

     private byte[] encodeDigest(String text) { 
      MessageDigest digest; 
      try { 
       digest = MessageDigest.getInstance(MESSAGEDIGEST_ALGORITHM); 
       return digest.digest(text.getBytes()); 
      } catch (NoSuchAlgorithmException e) { 
       Log.e(TAG, "No such algorithm " + MESSAGEDIGEST_ALGORITHM, e); 
      } 

      return null; 
     } 
} 

MainActivity:

public void clck(View v) { 
     try { 

      Crypto crpt = new Crypto("MyDifficultPassw"); 
      System.out.println(crpt.encryptAsBase64("tryToEncrypt".getBytes())); 

     } catch (Exception e) { 
      System.out.println(e.toString()); 
     } 

    } 

的outpıt是:2xrT + 9gHAw4Nh9H57kluwQ == ASP.Net方:

protected void Page_Load(object sender, EventArgs e) 
     { 
       Crypto crp = new Crypto("MyDifficultPassw"); 
       string asd = crp.DecryptFromBase64("2xrT+9gHAw4Nh9H57kluwQ=="); 
     } 

     public class Crypto 
     { 
      private ICryptoTransform rijndaelDecryptor; 
      // Replace me with a 16-byte key, share between Java and C# 
      private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 

      public Crypto(string passphrase) 
      { 
       byte[] passwordKey = encodeDigest(passphrase); 
       RijndaelManaged rijndael = new RijndaelManaged(); 
       rijndaelDecryptor = rijndael.CreateDecryptor(passwordKey, rawSecretKey); 
      } 

      public string Decrypt(byte[] encryptedData) 
      { 
       byte[] newClearData = rijndaelDecryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length); 
       return Encoding.ASCII.GetString(newClearData); 
      } 

      public string DecryptFromBase64(string encryptedBase64) 
      { 
       return Decrypt(Convert.FromBase64String(encryptedBase64)); 
      } 

      private byte[] encodeDigest(string text) 
      { 
       MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider(); 
       byte[] data = Encoding.ASCII.GetBytes(text); 
       return x.ComputeHash(data); 
      } 
     } 

     static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key 
, byte[] IV) 
     { 
      // Check arguments. 
      if (cipherText == null || cipherText.Length <= 0) 
       throw new ArgumentNullException("cipherText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("Key"); 

      // Declare the string used to hold 
      // the decrypted text. 
      string plaintext = null; 

      // Create an Aes object 
      // with the specified key and IV. 
      using (Aes aesAlg = Aes.Create()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 
       aesAlg.Padding = PaddingMode.None; 

       // Create a decrytor to perform the stream transform. 
       ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key 
, aesAlg.IV); 



       // Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 

        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt 
, decryptor, CryptoStreamMode.Read)) 
        { 

         using (StreamReader srDecrypt = new StreamReader(
csDecrypt)) 
         { 

          // Read the decrypted bytes from the decrypting 

          // and place them in a string. 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 

      } 

      return plaintext; 

     }