“Padding is invalid and cannot be removed” using AesManaged
我正在尝试使用aesmanaged进行简单的加密/解密,但在尝试关闭解密流时,我总是遇到一个异常。这里的字符串得到了正确的加密和解密,然后在console.writeline打印正确的字符串后,我得到了cryptographicException"padding was invalid and cannot be removed"。
有什么想法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | MemoryStream ms = new MemoryStream(); byte[] rawPlaintext = Encoding.Unicode.GetBytes("This is annoying!"); using (Aes aes = new AesManaged()) { aes.Padding = PaddingMode.PKCS7; aes.Key = new byte[128/8]; aes.IV = new byte[128/8]; using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(rawPlaintext, 0, rawPlaintext.Length); cs.FlushFinalBlock(); } ms = new MemoryStream(ms.GetBuffer()); using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read)) { byte[] rawData = new byte[rawPlaintext.Length]; int len = cs.Read(rawData, 0, rawPlaintext.Length); string s = Encoding.Unicode.GetString(rawData); Console.WriteLine(s); } } |
诀窍是使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | byte[] rawPlaintext = System.Text.Encoding.Unicode.GetBytes("This is all clear now!"); using (Aes aes = new AesManaged()) { aes.Padding = PaddingMode.PKCS7; aes.KeySize = 128; // in bits aes.Key = new byte[128/8]; // 16 bytes for 128 bit encryption aes.IV = new byte[128/8]; // AES needs a 16-byte IV // Should set Key and IV here. Good approach: derive them from // a password via Cryptography.Rfc2898DeriveBytes byte[] cipherText= null; byte[] plainText= null; using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(rawPlaintext, 0, rawPlaintext.Length); } cipherText= ms.ToArray(); } using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherText, 0, cipherText.Length); } plainText = ms.ToArray(); } string s = System.Text.Encoding.Unicode.GetString(plainText); Console.WriteLine(s); } |
另外,我想您知道您需要显式设置aesmanaged实例的模式,并使用system.security.cryptography.rfc2898派生字节从密码和salt派生密钥和iv。
参见:-审美管理
此异常可能是由于许多加密参数中的任何一个不匹配造成的。
我使用security.cryptography.debug接口跟踪加密/解密方法中使用的所有参数。
最后我发现我的问题是,我在设置
没有人回答,实际上memoryStream.getBuffer返回分配的缓冲区,而不是该缓冲区中的实际数据。在这种情况下,它返回256字节的缓冲区,而它只包含32字节的加密数据。
byte[] rawData = new
byte[rawPlaintext.Length];
您需要读取缓冲区的长度,这可能包括必要的填充(IIRC,已经有几年了)。