【问题标题】:C# "Bad Data" exception when decrypting encrypted file解密加密文件时出现 C#“Bad Data”异常
【发布时间】:2011-04-08 06:37:52
【问题描述】:

嘿,我对加密和解密非常陌生,老实说,甚至是 c# 语言。基本上,我有一个 tcp 聊天服务器,可以“保存”日志并加密文本文件。这就是我加密的方式(基于 MSDN 示例):

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();
}

当我检查加密流对象时,它说它抛出了一个异常,“流不支持搜索”。

任何帮助将不胜感激!

【问题讨论】:

    标签: c# file encryption cryptostream


    【解决方案1】:

    这里:

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

    您将直接关闭fsOut,而不关闭cryptostream。这意味着加密流没有机会刷新任何最终块等。

    另外:

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

    【讨论】:

    • 谢谢!我真的真的需要更多地研究这个。我正在试验 MSDN 中的代码示例,但不知道它们到底做了什么。我将 FlushFinalBlock() 调用到 cryptostream 并从输入文件中删除了 - 1 并解决了它。谢谢!
    【解决方案2】:
      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 "";
           }
       }
    

    【讨论】:

      【解决方案3】:

      解决我的问题是在创建文件时在加密流上调用 FlushFinalBlock

                      CryptoStream cryptostream = new CryptoStream(memoryStream, this._encryptionKeyHelper.Encryptor(), CryptoStreamMode.Write);
      
                  xmlser.Serialize(cryptostream, builderObject);
      
                  cryptostream.FlushFinalBlock();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-10
        • 1970-01-01
        • 2019-09-02
        • 1970-01-01
        • 1970-01-01
        • 2021-05-13
        相关资源
        最近更新 更多