AES解密失败,“填充无效,无法删除”

我正在使用Java编写的服务器进行跨平台应用程序,所以我最终使用C#for Windows。 我终于在这两种语言中克服了BigIntegers不同字节的所有障碍(Java:big endian,C#:little),所以我也成功地进行了密钥交换。 现在这就是问题所在,在Java中我使用AES/CBC/PKCS5Padding进行加密,但在C#中没有可用的PKCS5, 但正如我在其他post中读到的这个主题在SO上,PKCS7被告知与PKCS5相同或者Java确实使用PKCS7而不是PKCS5。 我不知道什么是正确的。

所以这是代码:

 using (System.Security.Cryptography.RijndaelManaged rijndael = new System.Security.Cryptography.RijndaelManaged()) { byte[] iv = new byte[16]; for (int i = 0; i < 16; i++) iv[i] = 0; rijndael.Padding = PaddingMode.PKCS7; rijndael.Mode = CipherMode.CBC; rijndael.Key = Sys.PrivateKey; rijndael.KeySize = 128; rijndael.BlockSize = 128; rijndael.IV = iv; Sys.LogWrite("Decrypt input bytes length: " + buff.Length + ", keyLength: " + Sys.PrivateKey.Length); Sys.LogWriteBuffer("Input bytes", buff); Sys.LogWriteBuffer("Input key", Sys.PrivateKey); ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV); buff=rijndael.CreateDecryptor().TransformFinalBlock(buff, 0, buff.Length); Sys.LogWriteBuffer("buffer: ", buff); } 

请忽略IV始终为00 00 00 00,这仅用于测试目的。 数据始终来自服务器,密钥在密钥交换中生成:

 Decrypt input bytes length: 32, keyLength: 16 Input bytes: 7C 25 3F 49 9E D5 51 67 E2 86 F9 86 2E C1 8F 22 70 51 65 74 FC 39 2C 52 A6 83 36 B5 9A C7 27 B9 Input key: 1C 13 C2 33 50 57 00 DB FD 60 E2 1C 27 2A A5 00 

如果我把它放到任何在线AES解密器这样的http://aes.online-domain-tools.com/我总能得到正确的结果: [[27,{"Established":true}]]但是在C#我只得到这个:

 System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed. at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast) at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) 

我甚至尝试过PaddingMode.None,它没有抛出任何exception,但输出只是随机字节。 即使在线解密器可以正确解决它,我做错了什么?

其他示例输入数据应该产生相同的结果[[27,{"Established":true}]]

 Decrypt input bytes length: 32, keyLength: 16 Input bytes: 85 5C 55 24 44 B8 77 A5 EF CE E7 A1 45 EC F3 84 2F 8B 74 1F AB D9 BE D0 82 64 BC 0D B0 50 73 63 Input key: B2 21 FA 17 63 E6 4C 25 48 03 84 64 8B 70 05 00 Decrypt input bytes length: 32, keyLength: 16 Input bytes: 8B FC 47 B4 91 05 B7 E1 6C 0E 61 78 D2 51 6B 77 EF 80 30 49 37 05 DA 79 47 52 D1 24 B9 DE A7 F3 Input key: E7 BF E0 AA AC F1 26 42 06 D6 59 44 F9 33 74 63 

请注意,IV始终是16个空字节。

我终于找到了这个问题而且令人难以置信! 而不是这样创建解密器:

 ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV); 

我应该以这种方式创建它:

 ICryptoTransform decryptor = rijndael.CreateDecryptor(Sys.PrivateKey, iv); 

所以如果将来有人有类似的问题,这里已经是一般化的function:

  public static String Decrypt(byte[] buff, byte[] key, byte[] iv) { using (System.Security.Cryptography.RijndaelManaged rijndael = new System.Security.Cryptography.RijndaelManaged()) { rijndael.Padding = PaddingMode.PKCS7; rijndael.Mode = CipherMode.CBC; rijndael.KeySize = 128; rijndael.BlockSize = 128; ICryptoTransform decryptor = rijndael.CreateDecryptor(key, iv); System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(buff); CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); byte[] output = new byte[buff.Length]; int readBytes = cryptoStream.Read(output, 0, output.Length); return System.Text.Encoding.UTF8.GetString(output, 0, readBytes); } } 

希望能帮助到你。