2014-09-20 129 views
0

嘿所有我想串行化一個字符串列表到一個文件,然後加密它。 目前它只是不工作。 mscorlib.dll中發生未處理的類型'System.Runtime.Serialization.SerializationException'異常加密/解密一個序列化文件

附加信息:二進制流'199'不包含有效的BinaryHeader。可能的原因是序列化和反序列化之間無效的流或對象版本更改。

然後,我需要解密和deseralize它。繼承人是我到目前爲止有:

加密和seralizing:

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); 


     } 
    } 
} 

和聯合國seralizing和解密:

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]); 
    } 
} 
+0

發佈完整例外。 – 2014-09-20 18:44:01

+0

我發佈了完整的例外,謝謝 – Peter 2014-09-20 19:06:11

+0

是*密碼*在* EncryptFile *「Y8LwUKQVJkqRz2ZAKsAMtFWY」? – 2014-09-20 19:09:49

回答

0

我看到的問題是,你實際上並沒有加密數據。我喜歡描繪加密過程的方式是將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落後於cryptoStreamSerialize方法是通過cryptoStream(「門戶」)「推送」來自lines的數據,並將其轉換爲fileStream


另外,處理你的IDisposable對象是相當重要的。請務必致電Dispose()或(更好)將它們放入using聲明。您正在使用的對象Rfc2898DeriveBytesRijndael未被處置。