[英]AES C# File Encryption - stream writes only 16 bytes
这是我的代码片段,它应该加密文件并将密码写入新文件。 代码与Microsoft MSDN网页上的示例类似。
byte[] inputBuffer = new byte[InputFileStream.Length];
byte[] outputBuffer = new byte[InputFileStream.Length];
InputFileStream.Read(inputBuffer, 0, (int)InputFileStream.Length);
ICryptoTransform encryptor = AesInstance.CreateEncryptor(AesInstance.Key, AesInstance.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream stream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter encrypted = new StreamWriter(stream))
{
encrypted.Write(inputBuffer);
}
outputBuffer = memoryStream.ToArray();
OutputFileStream.Write(outputBuffer, 0, (int)outputBuffer.Length);
}
}
OutputFileStream.Close();
InputFileStream.Close();`
问题是输入缓冲区从文件读取字节正确,但输出缓冲区似乎只有16个字节的数据。 结果是输出文件只有16个字节,即使输入文件很大。 哪里出错了? 各种模式存在问题,ECB,CBC等。
这个问题很古老,但值得更好的解释。 问题隐藏在StreamWriter
本身中。 此类应用于将文本写入流中。 但是, inputBuffer
不是文本。 这是一个字节数组!
encrypted.Write(inputBuffer);
等于
encrypted.Write(inputBuffer.ToString());
根据MSDN StreamWriter.Write(object)
:
通过调用该对象上的ToString方法,将对象的文本表示写入文本字符串或流。
正确的解决方案是将输入缓冲区直接写入CryptoStream
:
using (MemoryStream msEncrypt = new MemoryStream(outputBuffer))
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(inputBuffer, 0, inputBuffer.Length);
}
return msEncrypt.ToArray();
}
我相信你用的时候
encrypted.Write(inputBuffer);
你没有给写入者写入缓冲区的大小。
很多流都会进行缓冲,尤其是加密和压缩流。 在关闭/处理加密流之前,不要在MemoryStream上调用ToArray。
using (CryptoStream stream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter encrypted = new StreamWriter(stream))
{
encrypted.Write(inputBuffer);
}
}
OutputFileStream.Write(memoryStream.GetBuffer(),
0, (int)memoryStream.Length);
}
为了更清楚,完全丢失MemoryStream并在OutputFileStream之上创建加密流 - 即使对于大量数据,这也可以很好地工作。
好的,现在修好了。 感谢Marc的回应,我想出了它应该如何运作。 这是工作代码,如果有人以后需要它:
InputFileStream.Read(inputBuffer, 0, (int)InputFileStream.Length);
InputFileStream.Flush();
InputFileStream.Close();
using (MemoryStream msEncrypt = new MemoryStream(outputBuffer))
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(inputBuffer);
swEncrypt.Flush();
swEncrypt.Close();
}
csEncrypt.Flush();
csEncrypt.Close();
}
OutputFileStream.Write(outputBuffer, 0, (int)outputBuffer.Length);
OutputFileStream.Flush();
OutputFileStream.Close();
}
也许它不是完美的代码(我知道它可能是多余的)但它甚至对于大文件也能正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.