这似乎是在.NET框架的实现AES的你与你的行引用ICryptoTransform的错误:
provider.CreateDecryptor(keyBytes, ivBytes);
返回true为CanReuseTransform但它似乎不被清除解密后的输入缓冲区。有几个解决方案可以使这个工作。
选项1 创建第二个解密器并用此解密第二个字符串。
var key = new Rfc2898DeriveBytes("test password", Encoding.Unicode.GetBytes("test salt"));
var provider = new AesCryptoServiceProvider { Padding = PaddingMode.PKCS7, KeySize = 256 };
var keyBytes = key.GetBytes(provider.KeySize >> 3);
var ivBytes = key.GetBytes(provider.BlockSize >> 3);
var encryptor = provider.CreateEncryptor(keyBytes, ivBytes);
var decryptor = provider.CreateDecryptor(keyBytes, ivBytes);
var decryptor2 = provider.CreateDecryptor(keyBytes, ivBytes);
var testStringBytes = Encoding.Unicode.GetBytes("test string");
var testStringEncrypted = Convert.ToBase64String(encryptor.TransformFinalBlock(testStringBytes, 0, testStringBytes.Length));
//Prove that the encryption has resulted in the following string
Console.WriteLine(testStringEncrypted == "cc1zurZinx4yxeSB0XDzVziEUNJlFXsLzD2p9TWnxEc="); //Result: True
//Decrypt the encrypted text from a hardcoded string literal
var encryptedBytes = Convert.FromBase64String("cc1zurZinx4yxeSB0XDzVziEUNJlFXsLzD2p9TWnxEc=");
var testStringDecrypted = Encoding.Unicode.GetString(decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
//Decrypt the encrypted text from the string result of the encryption process
var encryptedBytes2 = Convert.FromBase64String(testStringEncrypted);
var testStringDecrypted2 = Encoding.Unicode.GetString(decryptor2.TransformFinalBlock(encryptedBytes2, 0, encryptedBytes2.Length));
//encryptedBytes and encryptedBytes2 should be identical, so they should result in the same decrypted text - but they don't:
Console.WriteLine(testStringDecrypted == "test string"); //Result: True
Console.WriteLine(testStringDecrypted2 == "test string"); //Result: True
Console.Read();
选项2 使用RijandaelManaged(或AesManaged)代替AesCryptoServiceProvider,应该是相同的算法(虽然AesCryptoServiceProvider和AesManaged既限制块大小为128)
var key = new Rfc2898DeriveBytes("test password", Encoding.Unicode.GetBytes("test salt"));
var provider = new RijndaelManaged { Padding = PaddingMode.PKCS7, KeySize = 256 };
var keyBytes = key.GetBytes(provider.KeySize >> 3);
var ivBytes = key.GetBytes(provider.BlockSize >> 3);
var encryptor = provider.CreateEncryptor(keyBytes, ivBytes);
var decryptor = provider.CreateDecryptor(keyBytes, ivBytes);
var testStringBytes = Encoding.Unicode.GetBytes("test string");
var testStringEncrypted = Convert.ToBase64String(encryptor.TransformFinalBlock(testStringBytes, 0, testStringBytes.Length));
//Prove that the encryption has resulted in the following string
Console.WriteLine(testStringEncrypted == "cc1zurZinx4yxeSB0XDzVziEUNJlFXsLzD2p9TWnxEc="); //Result: True
//Decrypt the encrypted text from a hardcoded string literal
var encryptedBytes = Convert.FromBase64String("cc1zurZinx4yxeSB0XDzVziEUNJlFXsLzD2p9TWnxEc=");
var testStringDecrypted = Encoding.Unicode.GetString(decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
//Decrypt the encrypted text from the string result of the encryption process
var encryptedBytes2 = Convert.FromBase64String(testStringEncrypted);
var testStringDecrypted2 = Encoding.Unicode.GetString(decryptor.TransformFinalBlock(encryptedBytes2, 0, encryptedBytes2.Length));
//encryptedBytes and encryptedBytes2 should be identical, so they should result in the same decrypted text - but they don't:
Console.WriteLine(testStringDecrypted == "test string"); //Result: True
Console.WriteLine(testStringDecrypted2 == "test string"); //Result: True
Console.Read();
选项3:改为使用使用说明
var key = new Rfc2898DeriveBytes("test password", Encoding.Unicode.GetBytes("test salt"));
var provider = new AesCryptoServiceProvider { Padding = PaddingMode.PKCS7, KeySize = 256 };
var keyBytes = key.GetBytes(provider.KeySize >> 3);
var ivBytes = key.GetBytes(provider.BlockSize >> 3);
var encryptor = provider.CreateEncryptor(keyBytes, ivBytes);
var testStringBytes = Encoding.Unicode.GetBytes("test string");
var testStringEncrypted = Convert.ToBase64String(encryptor.TransformFinalBlock(testStringBytes, 0, testStringBytes.Length));
//Prove that the encryption has resulted in the following string
Console.WriteLine(testStringEncrypted == "cc1zurZinx4yxeSB0XDzVziEUNJlFXsLzD2p9TWnxEc="); //Result: True
//Decrypt the encrypted text from a hardcoded string literal
var encryptedBytes = Convert.FromBase64String("cc1zurZinx4yxeSB0XDzVziEUNJlFXsLzD2p9TWnxEc=");
string testStringDecrypted, testStringDecrypted2;
using (var decryptor = provider.CreateDecryptor(keyBytes, ivBytes))
{
testStringDecrypted =
Encoding.Unicode.GetString(decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
}
//Decrypt the encrypted text from the string result of the encryption process
var encryptedBytes2 = Convert.FromBase64String(testStringEncrypted);
using (var decryptor = provider.CreateDecryptor(keyBytes, ivBytes))
{
testStringDecrypted2 =
Encoding.Unicode.GetString(decryptor.TransformFinalBlock(encryptedBytes2, 0, encryptedBytes2.Length));
}
//encryptedBytes and encryptedBytes2 should be identical, so they should result in the same decrypted text - but they don't:
Console.WriteLine(testStringDecrypted == "test string"); //Result: True
Console.WriteLine(testStringDecrypted2 == "test string"); //Result: True
Console.Read();
所以这个问题是重复使用。在深入讨论如何重置IV之前:这有多重要? –
您不提供任何第一个问题的代码,不能回答。 –
道歉 - 我不太明白你在说什么。代码示例是对更大的类中的问题的简化,它为字符串提供了简单的加密和解密方法。问题出现的原因是因为我正在使用BinaryFormatter将一些加密文本序列化到数据库中,并稍后再加载它,因此,当我解密时,调用加密文本的序列化结果不会生成相同的文本它并尝试使用它。希望澄清事情。 – wwarby