我正在尝试使用RijndaelManaged类对纯文本进行加密,然后解密加密的字符串以使其末尾具有相同的纯文本。
按如下所示加密纯文本时,一切都很好,
protected static string AESEncrypt(string plainText, string key)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged aes = new RijndaelManaged())
{
aes.KeySize = 256;
aes.BlockSize = 128;
var keyHold = new Rfc2898DeriveBytes(key, saltBytes, 1000);
aes.Key = keyHold.GetBytes(aes.KeySize / 8);
aes.IV = keyHold.GetBytes(aes.BlockSize / 8);
aes.Mode = CipherMode.CBC;
var bytesToBeEncrypted = Encoding.UTF8.GetBytes(plainText);
using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return Convert.ToBase64String(encryptedBytes);
}
例如,我通过将上述函数称为"encryptMe"
来加密此纯文本var encryptedString = AESEncrypt(plainText, "lockMe");
。结果为nKytZ86r0DDKSzD3ph+ntg==
。
然后我将加密的字符串发送到下面提到的功能,
protected static string AESDecrypt(string cryptedText, string key)
{
byte[] decryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged aes = new RijndaelManaged())
{
aes.KeySize = 256;
aes.BlockSize = 128;
var keyHold = new Rfc2898DeriveBytes(key, saltBytes, 1000);
aes.Key = keyHold.GetBytes(aes.KeySize / 8);
aes.IV = keyHold.GetBytes(aes.BlockSize / 8);
aes.Mode = CipherMode.CBC;
var bytesToBeDDecrypted = Encoding.UTF8.GetBytes(cryptedText);
using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDDecrypted, 0, bytesToBeDDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}
return Encoding.UTF8.GetString(decryptedBytes);
}
在这种方法下,代码在离开The input data is not a complete block
时抛出错误CryptoStream
。
我的KeySize
和BlockSize
都可以被8整除,我看不到自己忽略的地方。
答案 0 :(得分:3)
在AESDecrypt
中,您拥有:
var bytesToBeDDecrypted = Encoding.UTF8.GetBytes(cryptedText);
由于您正在传递base-64编码密码,因此应该改为
var bytesToBeDDecrypted = Convert.FromBase64String(cryptedText);
您还应该进行一些安全性改进。您应该将迭代计数从1000增加到更大,至少65K。该盐至少应为12个字节,并且每次加密均应随机生成。它不需要保密,通常将它放在密码之前很方便。然后,解密器从传入的密文中提取盐。您还应该使用消息身份验证代码(MAC)来防止篡改。请注意,AES-GCM模式以及某些其他模式都将此MAC包含为其操作的组成部分。但是,如果AES-GCM不可用,则HMAC-SHA256可能是并且可以接受的。