更新时间:2023-02-17 12:33:22
的技巧是使用 MemoryStream.ToArray()
。
我也改变了你的code,以便它使用了的CryptoStream
来写,在加密和解密。而你并不需要调用 CryptoStream.FlushFinalBlock()
明确,因为你必须在一个使用()
声明中,并刷新将发生在的Dispose()
。以下为我工作。
字节[] rawPlaintext = System.Text.Encoding.Uni code.GetBytes(这一切清楚了吧!);
使用(AES公司AES =新AesManaged())
{
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 128; //位数
aes.Key =新的字节[八分之一百二十八] // 16字节128位加密
aes.IV =新的字节[八分之一百二十八] // AES需要16个字节的第四
//应该设置密钥和IV在这里。好办法:从得到他们
//通过Cryptography.Rfc2898DeriveBytes密码
byte []的密文= NULL;
byte []的明文= NULL;
使用(MemoryStream的毫秒=新的MemoryStream())
{
使用(CryptoStream的CS =新的CryptoStream(MS,aes.CreateEncryptor(),CryptoStreamMode.Write))
{
cs.Write(rawPlaintext,0,rawPlaintext.Length);
}
密文= ms.ToArray();
}
使用(MemoryStream的毫秒=新的MemoryStream())
{
使用(CryptoStream的CS =新的CryptoStream(MS,aes.CreateDecryptor(),CryptoStreamMode.Write))
{
cs.Write(密文,0,cipherText.Length);
}
明文= ms.ToArray();
}
字符串s = System.Text.Encoding.Uni code.GetString(明文);
Console.WriteLine(多个);
}
另外,我想你知道你将要明确设置Mode在AesManaged实例,并使用System.Security.Cryptography.Rfc2898DeriveBytes导出密钥和IV从一个密码和盐
另见:
- AesManaged
I'm trying to get simple encryption/decryption working with AesManaged, but I keep getting an exception when trying to close the decryption stream. The string here gets encrypted and decrypted correctly, and then I get the CryptographicException "Padding was invalid and cannot be removed" after Console.WriteLine prints the correct string.
Any ideas?
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);
}
}
The trick is to use MemoryStream.ToArray()
.
I also changed your code so that it uses the CryptoStream
to Write, in both encrypting and decrypting. And you don't need to call CryptoStream.FlushFinalBlock()
explicitly, because you have it in a using()
statement, and that flush will happen on Dispose()
. The following works for me.
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);
}
Also, I guess you know you will want to explicitly set the Mode of the AesManaged instance, and use System.Security.Cryptography.Rfc2898DeriveBytes to derive the Key and IV from a password and salt.
see also:
- AesManaged