簡體   English   中英

加密/解密序列化文件

[英]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
    }
}

您可以想象一下一切之間的關系。 fileStreamcryptoStream后面。 Serialize方法是將lines的數據“通過” cryptoStream (“門戶”)“推”到fileStream


順便說一句,處置IDisposable對象非常重要。 確保對它們調用Dispose()或(最好)將它們放入using語句中。 您正在使用的Rfc2898DeriveBytesRijndael對象不會被丟棄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM