【问题标题】:RijndaelManaged - Encrypt/Decrypt a Stream in C#RijndaelManaged - 在 C# 中加密/解密流
【发布时间】:2019-04-08 13:38:49
【问题描述】:

我正在尝试加密和解密流(基础的 PDF 文档),但我遇到了问题。解密下载后尝试打开文档时,提示无法加载PDF文档

你知道为什么会这样吗?

这是加密的代码:

public EncryptResult EncryptStream(Stream dataStream, bool reuseIV = false)
    {
        RijndaelManaged crypto = new RijndaelManaged();
        crypto.Key = _key;

        if (!reuseIV || _iv == null)
        {
            // make a copy of the current IV
            _iv = crypto.IV;
        }
        else
        {
            // reuse the previous IV
            crypto.IV = _iv;
        }

        var result = new EncryptResult() { IV = crypto.IV };

        using (var encryptor = crypto.CreateEncryptor())
        {
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
               {
                    var byteArrayInput = new byte[dataStream.Length];
                    dataStream.Read(byteArrayInput, 0, byteArrayInput.Length);
                    csEncrypt.Write(byteArrayInput, 0, byteArrayInput.Length);
                    dataStream.Close();

                    result.Cipher = msEncrypt.ToArray();

                    msEncrypt.Flush();
                    msEncrypt.Position = 0;

                    return result;
                }
            }
        }
    }

和解密:

public Stream DecryptStream(byte[] cipher, byte[] iv)
    {
        RijndaelManaged crypto = new RijndaelManaged();
        crypto.Key = _key;
        crypto.IV = iv;

        crypto.Padding = PaddingMode.Zeros;

        using (var decryptor = crypto.CreateDecryptor())
        {
            using (MemoryStream msDecrypt = new MemoryStream(cipher))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    var sOutputFilename = new MemoryStream();
                    var fsDecrypted = new StreamWriter(sOutputFilename);
                    fsDecrypted.Write(new StreamReader(csDecrypt).ReadToEnd());

                    sOutputFilename.Position = 0;
                    return sOutputFilename;
                }
            }
        }
    }

提前致谢。

【问题讨论】:

  • 反对者,请解释一下?在我看来,这是一个完全合理的问题。
  • 除了尝试在 PDF 查看器中打开结果之外,您是否进行过任何结果检查?特别是,您是否比较了输入和输出?它们的大小大致相同吗?您是否比较了字节本身?只是一开始就错了还是全部错了?

标签: c# pdf encryption stream rijndaelmanaged


【解决方案1】:
using (MemoryStream msEncrypt = new MemoryStream())
{
   using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
   {
        //var byteArrayInput = new byte[dataStream.Length];
        //dataStream.Read(byteArrayInput, 0, byteArrayInput.Length);
        //csEncrypt.Write(byteArrayInput, 0, byteArrayInput.Length);
        dataStream.CopyTo(csEncrypt);
        dataStream.Close();

        //result.Cipher = msEncrypt.ToArray();  // not here - not flushed yet
        //msEncrypt.Flush();                    // don't need this
        //msEncrypt.Position = 0;            
    }
    result.Cipher = msEncrypt.ToArray();  
    return result;
}

在解密器中,去掉所有 StreamReader/StreamWriter 的东西。 PDF 文件被压缩,即二进制。但这是在解密之后,所以它不可能是你的错误。

using (var decryptor = crypto.CreateDecryptor())
{
    using (MemoryStream msDecrypt = new MemoryStream(cipher))
    {
       var outputStream = new MemoryStream();

        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        {               
            csDecrypt.CopyTo(outputStream );
        }
        outputStream .Position = 0;
        return outputStream ;
    }
}

【讨论】:

  • 请注意,根据 Stream 和实现,dataStream.Read(byteArrayInput, 0, byteArrayInput.Length); 可能无法读取 byteArrayInput.Length 字节。这就是它返回值的原因。
  • 同意,我复制了问题的形式可能不是这里的根本问题。现在修好了。
【解决方案2】:

一个问题是,您可能在流的末尾加密了多余的字节,您需要计算出读取或使用了多少字节

Stream.CopyTo Method

从当前流中读取字节并将它们写入另一个 流。

【讨论】:

  • 请解释 OPs 代码是如何“......可能在流的末尾加密多余的字节......”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
相关资源
最近更新 更多