如何加速这种加密方法 C# 文件流
How to Speed Up this Encryption Method C# Filestream
我的加密方法运行速度非常慢。加密数百 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();
}
感谢您的帮助!
您一次只读取一个字节。这会产生大量开销。
要加快处理速度,请立即开始使用更多字节或调用内部复制功能:
fsIn.CopyTo(cs);
一次读取一个字节是个糟糕的主意。使用内置的 Stream.CopyTo
方法:
fsIn.CopyTo(cs);
另请注意,从您派生密钥的同一个 material 派生 IV 是不好的做法,并且可能导致安全漏洞。在某些情况下,它甚至可以允许攻击者访问明文。您应该为每个加密操作随机生成一个 IV。
虽然加密速度可能很慢,但我不认为这是这里的问题。我怀疑是逐字节的 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
语句。
我的加密方法运行速度非常慢。加密数百 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();
}
感谢您的帮助!
您一次只读取一个字节。这会产生大量开销。
要加快处理速度,请立即开始使用更多字节或调用内部复制功能:
fsIn.CopyTo(cs);
一次读取一个字节是个糟糕的主意。使用内置的 Stream.CopyTo
方法:
fsIn.CopyTo(cs);
另请注意,从您派生密钥的同一个 material 派生 IV 是不好的做法,并且可能导致安全漏洞。在某些情况下,它甚至可以允许攻击者访问明文。您应该为每个加密操作随机生成一个 IV。
虽然加密速度可能很慢,但我不认为这是这里的问题。我怀疑是逐字节的 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
语句。