2012-05-03 21 views
4

我做了大量的研究,但找不到我的問題的答案。我在.NET中使用AES加密(Rijndael塊大小爲128位),並在Android(AES)中使用相同密碼進行解密,它們之間的鹽爲&。.NET中的加密和Android中的解密拋出BadPaddingException:pad block損壞

C#加密代碼片段:

 byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); 
     byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); 

     byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); 

     PasswordDeriveBytes password = new PasswordDeriveBytes(
                 passPhrase, 
                 saltValueBytes, 
                 hashAlgorithm, 
                 passwordIterations); 

     byte[] keyBytes = password.GetBytes(keySize/8); 

     RijndaelManaged symmetricKey = new RijndaelManaged(); 

     symmetricKey.Padding = PaddingMode.PKCS7; 

     symmetricKey.BlockSize = 128; 

     symmetricKey.Mode = CipherMode.CBC;   

     ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
                  keyBytes, 
                  initVectorBytes); 

     MemoryStream memoryStream = new MemoryStream();   

     CryptoStream cryptoStream = new CryptoStream(memoryStream, 
                 encryptor, 
                 CryptoStreamMode.Write); 
     cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 

     cryptoStream.FlushFinalBlock(); 

     byte[] cipherTextBytes = memoryStream.ToArray(); 

     memoryStream.Close(); 
     cryptoStream.Close(); 

     string cipherText = Convert.ToBase64String(cipherTextBytes); 

的Android解密代碼片段:

KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), iterationCount); 

    SecretKey key = SecretKeyFactory.getInstance( 
      "PBEWithSHA1And128BitAES-CBC-BC").generateSecret(keySpec); 

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); 

    cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv.getBytes())); 

    byte[] decrypted = cipher.doFinal(encrypted); 

cipher.doFinal調用拋出以下異常。

「05-02 18:17:38.239:W/System.err的(25547):javax.crypto.BadPaddingException:墊塊損壞」

我並設置在兩個.NET填充到 「PKCS7Padding」 Android和加密塊大小爲128位。

但是,在Android中加密解密在Android &工作正常。與.NET中的加密和.NET中的Decrypt一樣,也可以正常工作。

樣品測試:

String PlainText   = "hello world"; 
String EncryptedDotNetblob = "JyijoGEALMI25Zej7d+fMg=="; 
String EncryptedAndroidblob = "1HhuTQaLRJEK4zxI9FAO6A=="; 

,你可以在上面看到的斑點也不同。

有人知道這裏有什麼問題嗎?

+0

不知道,但不'String.toCharArray()'返回_characters_,這是在Java中的16位,而不是在_bytes_你有在C#代碼? –

+0

@Satish嗨,你有解決你的問題? –

回答

2

你得到的密鑰是不同的,這就是爲什麼你會得到一個錯誤(將它們記錄爲十六進制字符串來檢查)。 PasswordDeriveBytes使用了PBKDF1的修改版本,另一方面,SecretKeyFactory.getInstance("PBEWithSHA1And128BitAES-CBC-BC")爲您提供了一個派生PKCS#12指定的密鑰的關鍵工廠。這些是不同的算法,併產生不同的密鑰。使用.NET中的Rfc2898DeriveBytes和使用相同參數的SecretKeyFactory .getInstance("PBKDF2WithHmacSHA1")來獲得相同的密鑰。

-1

這裏是一個C#示例,你需要的IterationCount

protected void Page_Load(object sender, EventArgs e) 
{ 
    string value = ""; 
    string password = ""; 
    string salt = ""; 
    string iv = ""; 


    byte[] vectorBytes = Convert.FromBase64String(Server.UrlDecode(iv)); 
    byte[] cipherText = Convert.FromBase64String(Server.UrlDecode(value)); 

    Rfc2898DeriveBytes key1 = new Rfc2898DeriveBytes(password, StringToByteArray(salt)); //same as PBKDF2WithHmacSHA1 
    key1.IterationCount = 32; 
    byte[] keyBytes = key1.GetBytes(16); 

    string Answer = DecryptDataAES(cipherText, keyBytes, vectorBytes); //vectorBytes is good 

    //litAnswer.Text = Answer; 
} 

public static string DecryptDataAES(byte[] cipherText, byte[] key, byte[] iv) 
{ 
    string plaintext = null; 

    using (Rijndael rijndael = Rijndael.Create()) 
    { 
     rijndael.Key = key; 
     rijndael.IV = iv; 
     rijndael.Padding = PaddingMode.None; 

     ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.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)) 
       { 
        plaintext = srDecrypt.ReadToEnd(); 
       } 
      } 
     } 
    } 
    return plaintext; 
} 

public static byte[] StringToByteArray(String hex) 
{ 
    int NumberChars = hex.Length/2; 
    byte[] bytes = new byte[NumberChars]; 
    using (var sr = new StringReader(hex)) 
    { 
     for (int i = 0; i < NumberChars; i++) 
      bytes[i] = 
       Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16); 
    } 
    return bytes; 
}