2014-09-20 130 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未被处置。