使用 StreamWriter 写入 Stream(用于大 Stream 加密)
Using StreamWriter to write in a Stream (for large Stream encryption)
我正在关注 MSDN Example of Rijndael Encryption,只是我想加密 return 一个流。
以下无效。
它没有抛出异常,但是在单步执行代码后,return 值没有数据。
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;
}
看了documentation for the Stream.Writer class,觉得跟不支持写入Stream有关系。
我注意到有一个 'object' 类型参数,所以我假设它会起作用...对吗?如果没有,我该怎么做?
顺便说一下,我将一个 FileStream 传递给它。单步执行代码,plainStream 确实包含数据。
使用流级复制将一个流的内容复制到另一个流或使用相应的一对 Reader/Writer(例如 TextReader
/TextWriter
)- 如果您混合使用,很可能会得到错误的结果。 IE。流级副本:
plainStream.CopyTo(csEncrypt);
除了实际将数据写入加密流(而不是由于 StreamWrite.Write(Object)
调用而获得的 plainStream
类型名称),您还应该使用 MemoryStream.ToArray
复制结果内容- 否则你会得到 "object disposed exception".
复制代码应该如下所示,而不是 msEncrypt.CopyTo(encrypted);
var bytes = msEncrypt.ToArray();
encrypted.Write(bytes, 0, bytes.Length);
以下是一些用于对流进行加密和解密的示例函数(用您喜欢的算法替换算法):
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
我正在关注 MSDN Example of Rijndael Encryption,只是我想加密 return 一个流。
以下无效。
它没有抛出异常,但是在单步执行代码后,return 值没有数据。
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;
}
看了documentation for the Stream.Writer class,觉得跟不支持写入Stream有关系。
我注意到有一个 'object' 类型参数,所以我假设它会起作用...对吗?如果没有,我该怎么做?
顺便说一下,我将一个 FileStream 传递给它。单步执行代码,plainStream 确实包含数据。
使用流级复制将一个流的内容复制到另一个流或使用相应的一对 Reader/Writer(例如 TextReader
/TextWriter
)- 如果您混合使用,很可能会得到错误的结果。 IE。流级副本:
plainStream.CopyTo(csEncrypt);
除了实际将数据写入加密流(而不是由于 StreamWrite.Write(Object)
调用而获得的 plainStream
类型名称),您还应该使用 MemoryStream.ToArray
复制结果内容- 否则你会得到 "object disposed exception".
复制代码应该如下所示,而不是 msEncrypt.CopyTo(encrypted);
var bytes = msEncrypt.ToArray();
encrypted.Write(bytes, 0, bytes.Length);
以下是一些用于对流进行加密和解密的示例函数(用您喜欢的算法替换算法):
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