2013-03-04 40 views
2

我通过DataContractSerializer序列化对象没有任何问题。是否可以通过DataContractSerializer反序列化加密文件?

但是,如果我现在尝试序列化这个对象到一个加密的文件,我反序列化时得到一个异常。

这里是我的代码:

 public static bool SerializeDataContract<t>(Stream fileStream, t o, bool bCrypt = false) 
    { 
     DataContractSerializer serializer = new DataContractSerializer(typeof(t)); 
     if(bCrypt) 
     { 
      TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider(); 
      crypt.IV = CRYPT_INIT_VECTOR; 
      crypt.Key = CRYPT_KEY; 
      crypt.Padding = PaddingMode.Zeros; 

      using(CryptoStream cryptoStream = new CryptoStream(fileStream, crypt.CreateEncryptor(), CryptoStreamMode.Write)) 
      { 
       serializer.WriteObject(cryptoStream, o); 
       cryptoStream.Close(); 
      } 
     } 
     else 
      serializer.WriteObject(fileStream, o); 
     return true; 
    } 
    public static bool DeserializeDataContract<t>(Stream fileStream, out t o, bool bCrypt = false) 
    { 
     o = default(t); 

     try 
     { 
      DataContractSerializer serializer = new DataContractSerializer(typeof(t)); 
      if(bCrypt) 
      { 
       TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider(); 
       crypt.IV = CRYPT_INIT_VECTOR; 
       crypt.Key = CRYPT_KEY; 
       crypt.Padding = PaddingMode.Zeros; 

       using(CryptoStream cryptoStream = new CryptoStream(fileStream, crypt.CreateDecryptor(), CryptoStreamMode.Read)) 
       { 
        //TraceXML(cryptoStream); 

        o = (t)serializer.ReadObject(cryptoStream); 
        cryptoStream.Close(); 
       } 
      } 
      else 
      { 
       o = (t)serializer.ReadObject(fileStream); 
      } 
     } 
     catch(Exception ex) 
     { 
      return false; 
     } 

     return true; 
    } 

如果我打电话与bCrypt =假,一切都按预期这两种功能。但是,如果我用bCrypt = true调用函数,反序列化时会出现异常。

异常是(从德语转换为英语):SerializationException:根级别的数据无效。

如果我跟踪解密后读取的数据,数据对我来说似乎没问题,那看起来就像没有加密的序列化。

你知道吗,错误在我的代码中?

或者只是不可能使用DataContractSerializer加密?

回答

1

问题是加密数据填充了零,因此原始数据的长度不明显。

这里的删除他们,使反序列化运作的一种方式:

using(var cryptoStream = 
     new CryptoStream(fileStream, crypt.CreateDecryptor(), CryptoStreamMode.Read)) 
{    
    using(var reader = new StreamReader(cryptoStream)) 
    { 
     var s = reader.ReadToEnd().TrimEnd(new char[]{'\0'}); 

     using(var stream = new MemoryStream(Encoding.ASCII.GetBytes(s))) 
     { 
      o = (t)serializer.ReadObject(stream); 
     } 
    } 
} 
+0

这是我错过了什么,谢谢。 你确定没有问题,最后删除零?是否保证流末尾的所有零都是用于填充的? – MTR 2013-03-05 06:57:40

+0

这应该是因为你最初加密的xml永远不会有最终的零。 – Phil 2013-03-05 07:02:12

+0

你是对的,我没有意识到你正在删除解密流中的零。 – MTR 2013-03-05 07:18:37

0

如果您保存到流之后被decripted我想你可以伊斯利明白问题的所在

只是它在加密前比较序列化文件的文件。

如果它们相同,那么在解密程序完成其工作之前,您已经过早地进行了deserializyng。

我不认为你需要调用cryptoStream.Close();调用flush(),而不是

我会用一个MemoryStream作为缓冲区,而不是直接传递到CryptoStream的和DataContractSerializer的反之亦然的。

相关问题