2013-03-04 1 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

+0

Должно быть, так как вы изначально шифруете xml, у которого никогда не будет конечного нуля. – Phil

+0

Вы правы, я не понимал, что вы удаляете нули в расшифрованном потоке. – MTR

0

если вы сохраните в файл поток после того, как был decripted я думаю, вы можете понять, где Исли проблема

просто сравнить его с сериализованномом файла перед шифрованием.

Если они равны, то вы deserializyng это слишком рано, прежде чем decrypter выполняет свою работу.

Я не думаю, что вам нужно вызвать cryptoStream.Close(); вызова Flush() вместо

Я хотел бы использовать MemoryStream в качестве буфера вместо передачи непосредственно CryptoStream к DataContractSerializer и наоборот.