2011-11-03 80 views
1

为什么不能使用此代码?可能我犯了一些错误,但我找不到。使用MemoryStream时AES解密的错误结果

当我运行下面的代码时,我看到只有一部分消息被正确解密。据我所知,cryptoStreamReader.ReadToEnd()由于某种原因没有读取整个文件。

其实我已经解决了使用XmlTextReader和StringReader进行加密/解密而不是MemoryStream的任务。但我想知道那个代码有什么问题。任何人都可以帮我找到它吗?先谢谢你!

-

using System; 
using System.IO; 
using System.Runtime.Serialization; 
using System.Security.Cryptography; 
using System.Collections.Generic; 

namespace Tests 
{ 
    internal static class Program 
    { 
     private static void Main() 
     { 
#if GENERATE_DATA 
      var list = new List<int>(); 
      for (int i = 0; i <= 5 * 1024; i++) 
       list.Add(i); 
      using (var fileStream = new FileStream("data.xml", FileMode.Create)) 
      { 
       var serializer = new DataContractSerializer(list.GetType()); 
       serializer.WriteObject(fileStream, list); 
      } 
#endif 


      var originalData = GetData<List<int>>(); 

      SerializeAndEncrypt(originalData); 
      var restoredData = DecryptAndDeserialize<List<int>>(); 

      Console.ReadKey(); 
     } 

     private static T GetData<T>() 
     { 
      using (var fileStream = new FileStream("data.xml", FileMode.Open)) 
      { 
       var serializer = new DataContractSerializer(typeof(T)); 
       return (T)serializer.ReadObject(fileStream); 
      } 
     } 

     private const string ENCRYPTED_DATA_FILE_NAME = "data.enc"; 

     // 32 bytes 
     private static readonly byte[] KEY = new byte[] 
              { 
               1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 
               1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 
               1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 
               1, 2 
              }; 

     // 16 bytes 
     private static readonly byte[] INITIALIZATION_VECTOR = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 }; 

     private static string _toEncrypt; 
     private static string _decrypted; 

     private static void SerializeAndEncrypt<T>(T data) 
     { 
      var memoryStream = new MemoryStream(); 
      var serializer = new DataContractSerializer(typeof(T)); 
      serializer.WriteObject(memoryStream, data); 
      memoryStream.Position = 0L; 
      var memoryStreamReader = new StreamReader(memoryStream); 

      var fileStream = File.Open(ENCRYPTED_DATA_FILE_NAME, FileMode.Create); 
      var aes = Aes.Create(); 
      var cryptoTransform = aes.CreateEncryptor(KEY, INITIALIZATION_VECTOR); 
      var cryptoStream = new CryptoStream(fileStream, cryptoTransform, CryptoStreamMode.Write); 
      var cryptoStreamWriter = new StreamWriter(cryptoStream); 


      _toEncrypt = memoryStreamReader.ReadToEnd(); 
      cryptoStreamWriter.Write(_toEncrypt); 


      cryptoStream.Close(); 
      fileStream.Close(); 
      memoryStream.Close(); 
     } 

     private static T DecryptAndDeserialize<T>() 
     { 
      var fileStream = File.Open(ENCRYPTED_DATA_FILE_NAME, FileMode.Open); 
      var aes = Aes.Create(); 
      var cryptoTransform = aes.CreateDecryptor(KEY, INITIALIZATION_VECTOR); 
      var cryptoStream = new CryptoStream(fileStream, cryptoTransform, CryptoStreamMode.Read); 
      var cryptoStreamReader = new StreamReader(cryptoStream); 

      var memoryStream = new MemoryStream(); 
      var memoryStreamWriter = new StreamWriter(memoryStream); 


      // The following line is shorter than the original (_toEncrypt). Why? :(
      _decrypted = cryptoStreamReader.ReadToEnd(); 
      memoryStreamWriter.Write(_decrypted); 


      memoryStream.Position = 0L; 
      var serializer = new DataContractSerializer(typeof(T)); 
      var result = (T)serializer.ReadObject(memoryStream); 


      memoryStream.Close(); 
      cryptoStream.Close(); 
      fileStream.Close(); 

      return result; 
     } 
    } 
} 

-

+0

“只有一部分信息被正确解密” - 第一部分,最后一部分还是中间? –

+0

@HenkHolterman,第一部分是解密。最后一部分从某个位置截断。 –

回答

1

你必须刷新你StreamWriter为了得到写入底层 装置缓冲的数据:

private static void SerializeAndEncrypt<T>(T data) 
{     
    ... 

    _toEncrypt = memoryStreamReader.ReadToEnd(); 
    cryptoStreamWriter.Write(_toEncrypt); 

    // Flush your stream writer. So all buffered 
    // data get written to the underlying device. 
    cryptoStreamWriter.Flush(); 

    cryptoStream.Close(); 
    fileStream.Close(); 
    memoryStream.Close(); 
} 

private static T DecryptAndDeserialize<T>() 
{ 
    ... 

    _decrypted = cryptoStreamReader.ReadToEnd(); 
    memoryStreamWriter.Write(_decrypted); 

    // Flush buffered data. 
    memoryStreamWriter.Flush(); 

    memoryStream.Position = 0L; 
    var serializer = new DataContractSerializer(typeof(T)); 
    var result = (T)serializer.ReadObject(memoryStream); 
    memoryStream.Close(); 
    cryptoStream.Close(); 
    fileStream.Close(); 

    return result; 
} 

希望,这会有所帮助。

+0

非常感谢!最后它可以正常工作...并且我再次问过一个noob的问题。 :( –