我正在尝试将序列化的对象保存到加密文件中。这不是生产质量,我知道我这样做的方式会带来安全隐患,但是如果忽略这些隐患,我将拥有一个不会改变的资源(data.Settings.key)中的密钥,并且我有一个盐也是一个常数。
我的加密似乎有效,但是解密返回一个异常,说填充无效,并且在我尝试关闭CryptoStream时无法关闭。
private static byte[] decrypt(byte[] bytes)
{
var decryptor = algorithm.CreateDecryptor();
using (var sMemoryStream = new MemoryStream())
using (var sCryptoStream = new CryptoStream(sMemoryStream, decryptor, CryptoStreamMode.Write))
{
sCryptoStream.Write(bytes, 0, bytes.Length);
sCryptoStream.Close();
return sMemoryStream.ToArray();
}
}
algorithm变量与crypto方法使用的变量相同,并由该方法构建,该方法在类构造函数中调用:
private static SymmetricAlgorithm GetAlgorithm()
{
var algorithm = Rijndael.Create();
// Create key from salt and password in config
var rdb = new Rfc2898DeriveBytes(data.Settings.key, new byte[] {
0x44,0x61,0x79,0x6e,0x65,0x44,0x6f,0x75,0x67,0x61,0x6e
});
algorithm.Padding = PaddingMode.PKCS7;
// Set key and IV from rdb
algorithm.Key = rdb.GetBytes(32);
algorithm.IV = rdb.GetBytes(16);
return algorithm;
}
我已经尝试过更改算法中的填充模式,但是我不明白为什么加密时使用这种填充是可以的,但是现在解密时还是可以的。
如果有帮助,可以调用解密方法:
private static User OpenFile(String sUserName)
{
Console.WriteLine("Opening file...");
using (Stream sFileStream = new FileStream(data.Settings.dir + "data\\accounts\\" + sUserName + ".dat",
FileMode.Open, FileAccess.Read, FileShare.None))
using (Stream sMemoryStream = new MemoryStream())
{
// Read from File to memory stream
sFileStream.CopyTo(sMemoryStream);
// Decrypt data and store in new memory stream
byte[] bytes = new byte[sMemoryStream.Length];
Console.WriteLine("\tb:" + bytes.Length);
bytes = decrypt(bytes);
Console.WriteLine("\ta:" + bytes.Length);
Stream stream = new MemoryStream(bytes);
Console.WriteLine("\ts:" + bytes.Length);
// Deserialise memory stream and return as User object
User user = (User)bfFormatter.Deserialize(stream);
stream.Close();
return user;
}
}