在 C# 中循环遍历 50k 条记录。 在循环时,我调用 AES 256 算法来加密/解密提交的数字,加密后我将加密/解密文本分配给同一字段。 因此,对于 50K 记录,大约需要 40 分钟。 这是性能的约束。这是我的代码
public string Encrypt(string plainText)
{
try
{
_saltSize = 32;
encrypt_key = "200911381f7899d2482ab61fe8d15684469b17fc690";
if (string.IsNullOrEmpty(plainText))
{
throw new ArgumentNullException("plainText");
}
if (string.IsNullOrEmpty(encrypt_key))
{
throw new ArgumentNullException("Password_To_Encrypt_key");
}
var keyDerivationFunction = new Rfc2898DeriveBytes(encrypt_key, _saltSize);
byte[] saltBytes = keyDerivationFunction.Salt;
byte[] keyBytes = keyDerivationFunction.GetBytes(32);
byte[] ivBytes = keyDerivationFunction.GetBytes(16);
using (var aesManaged = new AesManaged())
{
aesManaged.KeySize = 256;
using (var encryptor = aesManaged.CreateEncryptor(keyBytes, ivBytes))
{
MemoryStream memoryStream = null;
CryptoStream cryptoStream = null;
return WriteMemoryStream(plainText, ref saltBytes, encryptor, ref memoryStream, ref cryptoStream);
}
}
}
catch (Exception)
{
throw;
}
}
我的猜测是你做了类似的事情:
public static byte[] EncryptRfc(byte[] plainText, string password, byte[] salt)
{
var keyGen = new Rfc2898DeriveBytes(password, salt);
var key = keyGen.GetBytes(32);
var iv = keyGen.GetBytes(16);
var cipher = new RijndaelManaged { Key = key, IV = iv };
byte[] cipherText;
using (var encryptor = cipher.CreateEncryptor()) {
using (var ms = new MemoryStream()) {
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) {
cs.Write(plainText, 0, plainText.Length);
cs.FlushFinalBlock();
cipherText = ms.ToArray();
}
}
}
return cipherText;
}
这里的问题是Rfc2898DeriveBytes
的初始化和对GetBytes
的后续调用,这在生成第一个密钥时需要相当长的时间。(有关详细信息,请参阅此博客文章。
您应该做的是从方法中取出Rfc2898DeriveBytes
:
public static byte[] EncryptRfc(string plaintext, byte[] key, byte[] iv)
{
var cipher = new RijndaelManaged { Key = key, IV = iv };
...
return cipherText;
}
然后用Key
调用加密函数,IV
...
var keyGen = new Rfc2898DeriveBytes(password, salt);
var key = keyGen.GetBytes(32);
...
foreach (var line in AllDataToEncryptCollectionOfStrings)
{
...
var iv = keyGen.GetBytes(16);
var encryptedData = EncryptRfc(plainText, key, iv);
...
}
这会将执行时间减少到原始时间的 1/4 左右。如果您需要它运行得更快,请对所有加密使用相同的密钥和 IV:
...
var keyGen = new Rfc2898DeriveBytes(password, salt);
var key = keyGen.GetBytes(32);
var iv = keyGen.GetBytes(16);
...
foreach (var line in AllDataToEncryptCollectionOfStrings)
{
...
var encryptedData = EncryptRfc(plainText, key, iv);
...
}
最后一段代码将在很短的时间内运行(在我的计算机上,对 EncryptRfc 的 50,000 次调用大约需要 300 毫秒)。
请注意,当使用相同的 IV 进行多次加密时,安全级别会降低。
但所有这些都只是猜测,因为您没有提供任何尝试代码。