从加密流读取到流的末尾
本文关键字:加密 密流 读取 | 更新日期: 2023-09-27 18:28:07
我在下面的代码中遇到了一些问题。我在一个需要加密的临时位置有一个文件,该函数对数据进行加密,然后将其存储在"pathToSave"位置。
检查时似乎没有正确处理整个文件——我的输出中缺少一些位,我怀疑这与while循环没有贯穿整个流有关。
顺便说一句,如果我在while循环之后尝试调用CryptStrm.Close(),我会收到一个异常。这意味着,如果我试图解密文件,我会得到一个已经在使用的文件错误!
尝试了所有的常规,我在这里查看了类似的问题,任何帮助都将是伟大的。
感谢
public void EncryptFile(String tempPath, String pathToSave)
{
try
{
FileStream InputFile = new FileStream(tempPath, FileMode.Open, FileAccess.Read);
FileStream OutputFile = new FileStream(pathToSave, FileMode.Create, FileAccess.Write);
RijndaelManaged RijCrypto = new RijndaelManaged();
//Key
byte[] Key = new byte[32] { ... };
//Initialisation Vector
byte[] IV = new byte[32] { ... };
RijCrypto.Padding = PaddingMode.None;
RijCrypto.KeySize = 256;
RijCrypto.BlockSize = 256;
RijCrypto.Key = Key;
RijCrypto.IV = IV;
ICryptoTransform Encryptor = RijCrypto.CreateEncryptor(Key, IV);
CryptoStream CryptStrm = new CryptoStream(OutputFile, Encryptor, CryptoStreamMode.Write);
int data;
while (-1 != (data = InputFile.ReadByte()))
{
CryptStrm.WriteByte((byte)data);
}
}
catch (Exception EncEx)
{
throw new Exception("Encoding Error: " + EncEx.Message);
}
}
编辑:
我已经假设我的问题是加密。我的解密可能是罪魁祸首
public String DecryptFile(String encryptedFilePath)
{
FileStream InputFile = new FileStream(encryptedFilePath, FileMode.Open, FileAccess.Read);
RijndaelManaged RijCrypto = new RijndaelManaged();
//Key
byte[] Key = new byte[32] { ... };
//Initialisation Vector
byte[] IV = new byte[32] { ... };
RijCrypto.Padding = PaddingMode.None;
RijCrypto.KeySize = 256;
RijCrypto.BlockSize = 256;
RijCrypto.Key = Key;
RijCrypto.IV = IV;
ICryptoTransform Decryptor = RijCrypto.CreateDecryptor(Key, IV);
CryptoStream CryptStrm = new CryptoStream(InputFile, Decryptor, CryptoStreamMode.Read);
String OutputFilePath = Path.GetTempPath() + "myfile.name";
StreamWriter OutputFile = new StreamWriter(OutputFilePath);
OutputFile.Write(new StreamReader(CryptStrm).ReadToEnd());
CryptStrm.Close();
OutputFile.Close();
return OutputFilePath;
}
好吧,这里有几个地方出了问题。
1.您的IV设置太大。如果密钥大小为256,则Rijndael的IV为16字节。如果您尝试设置的密钥的字节数超过此值,则会出现异常IV大小应该设置为块大小/8请参阅MSDN,这样您的IV大小是正确的。
- 您的填充模式为"无"。除非您的数据块大小完全正确,否则您将遇到问题。您可能想要选择填充模式
- 加密时,通常需要在写入加密流时调用FlushFInalBlock,以确保所有数据都写入流中
我发布了一些使用内存流的示例代码来显示加密和解密。
var tempData = "This is the text to encrypt. It's not much, but it's all there is.";
using (var rijCrypto = new RijndaelManaged())
{
byte[] encryptedData;
rijCrypto.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
rijCrypto.KeySize = 256;
using (var input = new MemoryStream(Encoding.Unicode.GetBytes(tempData)))
using (var output = new MemoryStream())
{
var encryptor = rijCrypto.CreateEncryptor();
using (var cryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
{
var buffer = new byte[1024];
var read = input.Read(buffer, 0, buffer.Length);
while (read > 0)
{
cryptStream.Write(buffer, 0, read);
read = input.Read(buffer, 0, buffer.Length);
}
cryptStream.FlushFinalBlock();
encryptedData = output.ToArray();
}
}
using (var input = new MemoryStream(encryptedData))
using (var output = new MemoryStream())
{
var decryptor = rijCrypto.CreateDecryptor();
using (var cryptStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
{
var buffer = new byte[1024];
var read = cryptStream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
output.Write(buffer, 0, read);
read = cryptStream.Read(buffer, 0, buffer.Length);
}
cryptStream.Flush();
var result = Encoding.Unicode.GetString(output.ToArray());
}
}
}
读取CryptoStream的另一种方法是使用CopyTo方法:
...
using (var output = new MemoryStream())
{
cryptStream.CopyTo(output);
return output.ToArray();
}
...
必须首先指定KeySize。这看起来像一个错误,例如,这适用于
using (var aes = new AesManaged())
{
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.IV = iv;
aes.Key = passwordHash;
aes.Padding = PaddingMode.PKCS7;
但这不是
using (var aes = new AesManaged())
{
aes.Mode = CipherMode.CBC;
aes.IV = iv;
aes.Key = passwordHash;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 256;