C# 解密加密文件时出现“Bad Data”异常

Rap*_*ael 2 c# encryption file cryptostream

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

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

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();
}
Run Code Online (Sandbox Code Playgroud)

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

任何帮助将不胜感激!

Jon*_*eet 5

这里:

    cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length);
    fsIn.Close();
    fsOut.Close();
Run Code Online (Sandbox Code Playgroud)

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

此外:

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

  • 谢谢!我真的真的需要更多地研究这个。我正在尝试 MSDN 上的代码示例,但不知道它们到底做了什么。我调用了 cryptostream 的 FlushFinalBlock() 并从输入文件中删除了 - 1 并解决了这个问题。谢谢! (2认同)