加密/解密序列化文件

时间:2014-09-20 18:39:11

标签: c# serialization encryption

嘿所有我试图将字符串列表序列化到文件,然后加密它。 目前它只是不工作。 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]);
    }
}

1 个答案:

答案 0 :(得分:0)

我看到的问题是您实际上并未加密数据。我喜欢描绘加密过程的方式是将CryptoStream想象成一个神奇的门户网站&#34;加密/解密数据。为了加密或解密,您需要通过&#34;门户网站推送或提取数据。从一边到另一边。

对加密代码进行简单更改应该可以解决问题:

<强>之前

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方法是&#34;推送&#34;来自linescryptoStream(&#34;门户&#34;)和fileStream的数据。


另外,处理IDisposable对象非常重要。确保在它们上面调用Dispose()或者(更好的是)将它们放入using语句中。您正在使用的Rfc2898DeriveBytesRijndael个对象未被处置。