[英]Encrypt/Decrypt a serialized file
嘿,我正在尝试将字符串列表序列化到文件中,然后对其进行加密。 目前,它只是无法正常工作。 mscorlib.dll中发生了类型为'System.Runtime.Serialization.SerializationException'的未处理异常
附加信息:二进制流“ 199”不包含有效的BinaryHeader。 可能的原因是序列化和反序列化之间无效的流或对象版本更改。
然后,我需要解密和反序列化它。 这是我到目前为止的内容:
加密和序列化:
public void EncryptFile(FileInfo targetFile, string password, List<string> lines)
{
int SaltSize = 8;
var keyGenerator = new Rfc2898DeriveBytes(password, SaltSize);
var rijndael = Rijndael.Create();
// BlockSize, KeySize in bit --> divide by 8
rijndael.IV = keyGenerator.GetBytes(rijndael.BlockSize / 8);
rijndael.Key = keyGenerator.GetBytes(rijndael.KeySize / 8);
using (var fileStream = targetFile.Create())
{
// write random salt
fileStream.Write(keyGenerator.Salt, 0, SaltSize);
using (var cryptoStream = new CryptoStream(fileStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
{
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
bformatter.Serialize(fileStream, lines);
}
}
}
并反序列化和解密:
int SaltSize = 8;
Dictionary<string, string> settings = new Dictionary<string, string>();
var fileStream = File.Open(SettingsFile, FileMode.Open);
var salt = new byte[SaltSize];
fileStream.Read(salt, 0, SaltSize);
// initialize algorithm with salt
var keyGenerator = new Rfc2898DeriveBytes("Y8LwUKQVJkqRz2ZAKsAMtFWY", salt);
var rijndael = Rijndael.Create();
rijndael.IV = keyGenerator.GetBytes(rijndael.BlockSize / 8);
rijndael.Key = keyGenerator.GetBytes(rijndael.KeySize / 8);
// decrypt
using (var cryptoStream = new CryptoStream(fileStream, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
{
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
List<string> settingsList = (List<string>)bformatter.Deserialize(cryptoStream);
foreach (string setting in settingsList)
{
string[] bothWords = setting.Split(',');
settings.Add(bothWords[0], bothWords[1]);
}
}
我看到的问题是您实际上并未在加密数据。 我想对加密过程进行描述的方式是将CryptoStream
想象成一个加密/解密数据的神奇“门户”。 为了加密或解密,您需要通过“门户”将数据从一侧推到另一侧。
对您的加密代码进行简单更改即可达到目的:
之前
using (var fileStream = targetFile.Create())
{
// write random salt
fileStream.Write(keyGenerator.Salt, 0, SaltSize);
using (var cryptoStream = new CryptoStream(fileStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
{
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
bformatter.Serialize(fileStream, lines);
}
}
后
using (var fileStream = targetFile.Create())
{
// write random salt
fileStream.Write(keyGenerator.Salt, 0, SaltSize);
using (var cryptoStream = new CryptoStream(fileStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
{
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
bformatter.Serialize(cryptoStream, lines); //changed the input stream to 'cryptoStream'
cryptoStream.FlushFinalBlock(); //added a call to FlushFinalBlock
}
}
您可以想象一下一切之间的关系。 fileStream
在cryptoStream
后面。 Serialize
方法是将lines
的数据“通过” cryptoStream
(“门户”)“推”到fileStream
。
顺便说一句,处置IDisposable对象非常重要。 确保对它们调用Dispose()
或(最好)将它们放入using
语句中。 您正在使用的Rfc2898DeriveBytes
和Rijndael
对象不会被丢弃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.