使用本机加密提供程序时.NET中的内存泄漏

kma*_*ks2 4 .net c# memory encryption

我有一个需要加密和解密字符串的应用程序.以下是我的解密方法:

  public static string Decrypt(string cipherText)
  {
     try
     {
        //Decrypt:
        byte[] keyArray;
        byte[] toDecryptArray = Convert.FromBase64String(cipherText);
        keyArray = UTF8Encoding.UTF8.GetBytes(key);
        AesCryptoServiceProvider Aes = new AesCryptoServiceProvider();
        Aes.Key = keyArray;
        Aes.Mode = CipherMode.CBC;
        Aes.Padding = PaddingMode.PKCS7;
        Aes.IV = IV;
        ICryptoTransform cTransform = Aes.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toDecryptArray, 0, toDecryptArray.Length);
        Aes.Clear();
        return UTF8Encoding.UTF8.GetString(resultArray, 0, resultArray.Length);
     }
     catch (Exception ex)
     {
        return "FAILED:*" + cipherText + "*" + ex.Message;
     }
  }
Run Code Online (Sandbox Code Playgroud)

然而,这似乎泄漏了.如您所见,所有变量都是本地范围的,因此在完成此块时应该释放它们.作为背景,我称这种方法有时几乎是不间断的.

为了确定我有泄漏我用很多请求淹没了我的服务器.通过仔细跟踪每个请求通过每个代码路径,我确定这段代码是罪魁祸首.当在我的记忆中评论时,使用率会急剧上升,当被注释掉(并且只是返回cipherText)时,内存使用会保持平稳.

HCL*_*HCL 21

AesCryptoServiceProvider实现IDisposable.尝试在using-block中使用它.像下面这样的东西:

using(AesCryptoServiceProvider Aes = new AesCryptoServiceProvider()){
        Aes.Key = keyArray; 
        Aes.Mode = CipherMode.CBC; 
        Aes.Padding = PaddingMode.PKCS7; 
        Aes.IV = IV; 
        using (ICryptoTransform cTransform = Aes.CreateDecryptor()){
            byte[] resultArray = cTransform.TransformFinalBlock(toDecryptArray, 0, toDecryptArray.Length); 
            Aes.Clear(); 
            return UTF8Encoding.UTF8.GetString(resultArray, 0, resultArray.Length); 
        }
}
Run Code Online (Sandbox Code Playgroud)

  • ICryptoTransform也实现了IDisposable,因此它也需要包装 (6认同)

Ral*_*rek 5

通常,您应该始终处置实现IDisposable的对象,例如AesCryptoServiceProvider.它们通常使用非托管资源,Garbagecollector不会清除这些资源.而不是

AesCryptoServiceProvider Aes = new AesCryptoServiceProvider();
Run Code Online (Sandbox Code Playgroud)

using (AesCryptoServiceProvider Aes = new AesCryptoServiceProvider())
{
}
Run Code Online (Sandbox Code Playgroud)