如何在使用 AES 256 算法 c#.net 时更快地遍历数据集

  • 本文关键字:net 数据集 遍历 算法 AES c#
  • 更新时间 :
  • 英文 :


在 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 进行多次加密时,安全级别会降低。

但所有这些都只是猜测,因为您没有提供任何尝试代码。

相关内容

  • 没有找到相关文章

最新更新