这是一个非常常见的例外,但显然我找到的解决方案都没有解决我的问题.
我有一个加密和解密方法;我加密字符串并将其写入文件,然后从文件中读取字符串并解密(理论上).实际上,我得到了一个
CryptographicException:要解密的数据长度无效
在进程的解密端.
以下是完成所有工作的Main()
种方法:
public static void Main()
{
var filename = "test.encrypted";
var plainText = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
string password = "A better password than this";
string salt = "Sodium Chloride";
var padding = PaddingMode.Zeros; // I have tried every padding mode to no avail
var encrypted = Encrypt<AesManaged>(plainText, password, salt, padding);
File.WriteAllBytes(filename, encrypted);
var fileBytes = File.ReadAllBytes(filename);
var decrypted = Decrypt<AesManaged>(fileBytes, password, salt, padding);
Console.ReadLine();
}
加密端:
static byte[] Encrypt<T>(string plainText, string password, string salt, PaddingMode padding)
where T : Symmetric算法rithm, new()
{
var saltBytes = Encoding.Unicode.GetBytes(salt);
var derivedBytes = new Rfc2898DeriveBytes(password, saltBytes);
using (var algorithm = new T())
{
algorithm.Padding = padding;
var key = derivedBytes.GetBytes(algorithm.KeySize >> 3);
byte[] iv = new byte[algorithm.BlockSize >> 3];
RNGCryptoServiceProvider.Create().GetNonZeroBytes(iv);
var transform = algorithm.CreateEncryptor(key, iv);
using (MemoryStream buffer = new MemoryStream())
using (CryptoStream cryptoStream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
using (StreamWriter writer = new StreamWriter(cryptoStream, Encoding.Unicode))
{
writer.Write(plainText);
writer.Flush();
// cryptoStream.FlushFinalBlock() is called after writer.Flush()
// or as part of the Dispose().
// Calling it here causes a "you can't call that twice" exception.
// prepend IV to the data
return iv.Concat(buffer.ToArray()).ToArray();
}
}
}
... 还有另一面
static byte[] Decrypt<T>(byte[] encryptedData, string password, string salt, PaddingMode padding)
where T : Symmetric算法rithm, new()
{
var saltBytes = Encoding.Unicode.GetBytes(salt);
var derivedBytes = new Rfc2898DeriveBytes(password, saltBytes);
using (var algorithm = new T())
{
algorithm.Padding = padding;
var key = derivedBytes.GetBytes(algorithm.KeySize >> 3);
//IV is at the beginning of the data
var iv = encryptedData.Take(algorithm.BlockSize >> 3).ToArray();
encryptedData = encryptedData.Skip(iv.Length).ToArray();
var transform = algorithm.CreateDecryptor(key, iv);
using (MemoryStream buffer = new MemoryStream())
using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
{
writer.Write(encryptedData);
writer.Flush();
return buffer.ToArray();
}
}
}