我正在尝试使用AesManaged进行简单的加密/解密,但在尝试关闭解密流时我一直遇到异常.这里的字符串被正确加密和解密,然后在Console.WriteLine输出正确的字符串后,我得到CryptographicException"Padding无效且无法删除".
有任何想法吗?
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); } }
Cheeso.. 50
诀窍是使用MemoryStream.ToArray()
.我还更改了您的代码,以便CryptoStream
在加密和解密时使用写入.并且您不需要CryptoStream.FlushFinalBlock()
显式调用,因为您在using()
语句中有它,并且将发生刷新Dispose()
.以下适用于我.
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.Rfc2898DeriveBytes 从密码和salt派生密钥和IV.
另见:
- AesManaged
诀窍是使用MemoryStream.ToArray()
.我还更改了您的代码,以便CryptoStream
在加密和解密时使用写入.并且您不需要CryptoStream.FlushFinalBlock()
显式调用,因为您在using()
语句中有它,并且将发生刷新Dispose()
.以下适用于我.
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.Rfc2898DeriveBytes 从密码和salt派生密钥和IV.
另见:
- AesManaged
此异常可能是由多个加密参数中的任何一个不匹配引起的.
我使用Security.Cryptography.Debug接口来跟踪加密/解密方法中使用的所有参数.
最后我发现我的问题是我KeySize
在设置Key
导致类重新生成随机密钥而不使用我最初设置的密钥之后设置了属性.