我的加密方法运行速度令人难以置信。加密数百MB的数据大约需要20分钟。我不确定我是否采取了正确的方法。任何帮助,想法,建议将不胜感激。
private void AES_Encrypt(string inputFile, string outputFile, byte[] passwordBytes, byte[] saltBytes)
{
FileStream fsCrypt = new FileStream(outputFile, FileMode.Create);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Padding = PaddingMode.Zeros;
AES.Mode = CipherMode.CBC;
CryptoStream cs = new CryptoStream(fsCrypt,
AES.CreateEncryptor(),
CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);
fsCrypt.Flush();
cs.Flush();
fsIn.Flush();
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
感谢您的帮助!
答案 0 :(得分:11)
虽然加密速度很慢,但我不希望这是问题。我怀疑这是逐字节的IO导致不必要的开销。解决问题的最简单方法是明智地调用Stream.CopyTo
- 当您处于此状态时,应该使用using
语句进行适当的清理:
private void AesEncrypt(string inputFile, string outputFile, byte[] passwordBytes, byte[] saltBytes)
{
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
RijndaelManaged aes = new RijndaelManaged
{
KeySize = 256,
BlockSize = 128,
Key = key.GetBytes(AES.KeySize / 8),
IV = key.GetBytes(AES.BlockSize / 8),
Padding = PaddingMode.Zeros,
Mode = CipherMode.CBC
};
using (var output = File.Create(outputFile))
{
using (var crypto = new CryptoStream(output, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
using (var input = File.OpenRead(inputFile))
{
input.CopyTo(crypto);
}
}
}
}
如其他答案所述,这不是产生IV的好方法。一般情况下,我更倾向于使用Rijndael.Create()
而不是指定RijndaelManaged
- 而且您可能也希望使用using
语句。
答案 1 :(得分:6)
答案 2 :(得分:2)
一次读取一个字节是个糟糕的主意。使用内置的Stream.CopyTo
方法:
fsIn.CopyTo(cs);
另请注意,从您从中获取密钥的相同材料中获取IV是不好的做法,并且可能导致安全漏洞。在某些情况下,它甚至可以允许攻击者访问明文。您应该为每个加密操作随机生成一个IV。