2011-04-08 42 views
1

嘿,我对加密和解密甚至是c#语言都很陌生。基本上,我有一个tcp聊天服务器“保存”日志并加密文本文件。这是我如何加密(基于MSDN示例):解密加密文件时出现C#“Bad Data”异常

public static void EncryptFile(string strInputFileName, string strOutputFileName, string strKey) 
{ 
    FileStream fsIn = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read); 
    FileStream fsOut = new FileStream(strOutputFileName, FileMode.Create, FileAccess.Write); 

    DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 
    des.Key = ASCIIEncoding.ASCII.GetBytes(strKey); 
    des.IV = ASCIIEncoding.ASCII.GetBytes(strKey); 


    ICryptoTransform desencrypt = des.CreateEncryptor(); 
    CryptoStream cryptostream = new CryptoStream(fsOut, desencrypt, CryptoStreamMode.Write); 

    byte[] byteArrayInput = new byte[fsIn.Length - 1]; 
    fsIn.Read(byteArrayInput, 0, byteArrayInput.Length); 
    cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length); 

    fsIn.Close(); 
    fsOut.Close(); 
} 

该方法成功完全加密文件。这是我的解密方法:

public static void DecryptFile(string strInputFileName, string strOutputFileName, string strKey) 
{ 
    DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 
    des.Key = ASCIIEncoding.ASCII.GetBytes(strKey); 
    des.IV = ASCIIEncoding.ASCII.GetBytes(strKey); 

    byte[] te = new byte[1024]; 
    FileStream fsRead = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read); 
    ICryptoTransform desdecrypt = des.CreateDecryptor();   

    CryptoStream cryptostream = new CryptoStream(fsRead, desdecrypt, CryptoStreamMode.Read); 
    StreamWriter fsDecrypted = new StreamWriter(strOutputFileName);    

    fsDecrypted.Write(new StreamReader(cryptostream).ReadToEnd());//This is where the "Bad Data" occurs. 
    fsDecrypted.Flush(); 
    fsDecrypted.Close(); 
    fsRead.Close(); 
} 

当我检查CryptoStream的对象,它说,它已抛出异常,“流不支持查找”。

任何帮助将不胜感激!

回答

3

这里:

cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length); 
    fsIn.Close(); 
    fsOut.Close(); 

您要关闭fsOut直接,无需关闭cryptostream。这意味着加密流不得到机会刷新任何最终块等

此外:代替

  • 使用using语句手动调用关闭或Dispose
  • 你当前正在调用Read一次,并假设它会读取所有的数据 - 你没有检查返回值。 (由于某种原因,你也删除了输入文件的最后一个字节......为什么?)一般来说,你应该循环读取一个缓冲区,然后写出你读取的很多字节,直到Read方法返回0如果你使用.NET 4,Stream.CopyTo是你的朋友。
+2

谢谢!我真的很需要学习这个更多。我正在尝试使用MSDN的代码示例,而不知道它们的确做了什么。 我将FlushFinalBlock()调用到cryptostream,并从输入文件中移除了-1,并解决了这个问题。谢谢! – Raphael 2011-04-08 07:05:06

1
objCryptStream.CopyTo(stream); 

为我工作,完整的代码是

public static string DecryptString(string encriptedText, string key) 
    { 

     try 
     { 


      //Convert the text into bytest 
      byte[] ecriptedBytes = System.Convert.FromBase64String(encriptedText); 

      // Create a memory stream to the passed buffer 
      MemoryStream objMemStream = new MemoryStream(ecriptedBytes); 

      //Set the legal keys and initialization verctors 
      objCrptoService.Key = GetLegalsecretKey(key); 
      objCrptoService.IV = GetLegalIV(); 

      // Create a CryptoStream using the memory stream and the cryptographic service provider version 
      // of the Data Encryption stanadard algorithm key 
      CryptoStream objCryptStream = new CryptoStream(objMemStream, objCrptoService.CreateDecryptor(), CryptoStreamMode.Read); 

      // Create a StreamReader for reading the stream. 
      //StreamReader objstreamReader = new StreamReader(objCryptStream); 
      MemoryStream stream = new MemoryStream(); 
      objCryptStream.CopyTo(stream); 
      stream.Position = 0; 
      StreamReader R = new StreamReader(stream); 
      string outputText = R.ReadToEnd(); 

      // Close the streams. 
      R.Close(); 
      objCryptStream.Close(); 
      objMemStream.Close(); 

      return outputText; 
     } 
     catch (Exception exc) 
     { 
      return ""; 
     } 
    }