繁体   English   中英

使用StreamWriter写入流(用于大流加密)

[英]Using StreamWriter to write in a Stream (for large Stream encryption)

我正在关注Rijndael加密MSDN示例 ,只是我想加密并返回一个流。

以下不起作用。

它没有抛出任何异常,但在单步执行代码后,返回值没有数据。

        public static Stream EncryptStream(Stream plainStream, byte[] Key, byte[] IV)
        {

            var encrypted = new MemoryStream()

            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for encryption. 
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {

                            //Write all data to the stream.
                            swEncrypt.Write(plainStream);
                        }
                        msEncrypt.CopyTo(encrypted);
                    }
                }
            }
            return encrypted;


        }

我查看了Stream.Writer类文档 ,认为它与它有关,不支持写入Stream。

我注意到有一个'对象'类型参数,所以我假设它会工作......这是正确的吗? 如果没有,我该怎么办?

顺便说一句,我将FileStream传递给它。 逐步执行代码,plainStream确实包含数据。

以下是一些加密和解密流的示例函数(用您喜欢的算法替换算法):

public static void Decrypt(Stream input, Stream output, byte[] key, byte[] iv)
{
    using (SymmetricAlgorithm algo = SymmetricAlgorithm.Create()) // Creates the default implementation, which is RijndaelManaged. 
    {
        using (CryptoStream stream = new CryptoStream(input, algo.CreateDecryptor(key, iv), CryptoStreamMode.Read))
        {
            byte[] bytes = new byte[16];
            int read;
            do
            {
                read = stream.Read(bytes, 0, bytes.Length);
                output.Write(bytes, 0, read);
            }
            while (read > 0);
        }
    }
}

public static void Encrypt(Stream input, Stream output, byte[] key, byte[] iv)
{
    using (SymmetricAlgorithm algo = SymmetricAlgorithm.Create()) //Creates the default implementation, which is RijndaelManaged. 
    {
        using (CryptoStream stream = new CryptoStream(output, algo.CreateEncryptor(key, iv), CryptoStreamMode.Write))
        {
            byte[] bytes = new byte[16];
            int read;
            do
            {
                read = input.Read(bytes, 0, bytes.Length);
                stream.Write(bytes, 0, read);
            }
            while (read > 0);
        }
    }
}

您可以将它们与任何输出流一起使用。 如果你想写一个大的输出流,你可以直接使用那个输出流(例如FileStream或ASP.NET Response.OutputStream等),你不应该使用一个中间的MemoryStream,它会消耗内存而不是真正的目的。

话虽这么说,如果你真的想使用MemoryStream,你会这样做:

MemoryStream output = new MemoryStream();
Encrypt(input, output, key, iv);
output.Position = 0; // rewind the stream, so you can use it from the beginning

使用流级别复制将一个流的内容复制到另一个流或使用相应的读/写器对(如TextReader / TextWriter ) - 如果混合比最有可能得到错误的结果。 即流级副本:

 plainStream.CopyTo(csEncrypt);

除了实际将数据写入加密流(而不是由于StreamWrite.Write(Object)调用而得到的plainStream的类型名称)之外,您应该使用MemoryStream.ToArray来复制结果内容 - 否则您将获得“对象处置异常” 。

复制代码应如下所示,而不是msEncrypt.CopyTo(encrypted);

var bytes = msEncrypt.ToArray();
encrypted.Write(bytes, 0, bytes.Length);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM