C#“坏数据”解密加密文件时出现异常

发布于 2024-10-31 06:45:11 字数 1884 浏览 0 评论 0原文

嘿,我对加密和解密很陌生,说实话,甚至对 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();
}

当我检查 cryptostream 对象时,它说它抛出了异常,“Stream 不支持查找”。

任何帮助将不胜感激!

Hey I'm very new to encryption and decryption, or even the c# language to be honest. Basically, I have a tcp chat server that "saves" logs and encrypts the text file. This is how I encrypt (based from the MSDN sample):

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

The method success fully encrypts files. This is my decrypt method:

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

And when I inspect the cryptostream object, it says that it has thrown an exception, "Stream does not support seeking".

Any help would be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

娇俏 2024-11-07 06:45:11

此处:

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

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

另外:

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

Here:

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

You're closing fsOut directly, without closing cryptostream. That means the crypto stream doesn't get the chance to flush any final blocks etc.

Additionally:

  • Use using statements instead of manually calling Close or Dispose
  • You're currently calling Read once, and assuming it will read all the data - you're not checking the return value. (You're also removing the last byte of the input file for some reason... why?) In general, you should loop round, reading into a buffer and then writing out however many bytes you read, until the Read method returns 0. If you're using .NET 4, Stream.CopyTo is your friend.
樱娆 2024-11-07 06:45:11
  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 "";
       }
   }
  objCryptStream.CopyTo(stream);

Worked for me, complete code is

 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 "";
       }
   }
风轻花落早 2024-11-07 06:45:11

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

                CryptoStream cryptostream = new CryptoStream(memoryStream, this._encryptionKeyHelper.Encryptor(), CryptoStreamMode.Write);

            xmlser.Serialize(cryptostream, builderObject);

            cryptostream.FlushFinalBlock();

What fixed my issue was calling FlushFinalBlock on cryptostream, When creating the file

                CryptoStream cryptostream = new CryptoStream(memoryStream, this._encryptionKeyHelper.Encryptor(), CryptoStreamMode.Write);

            xmlser.Serialize(cryptostream, builderObject);

            cryptostream.FlushFinalBlock();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文