AesCryptoServiceProvider: Keys are not cleared from memory after use - by aaa444

Status : 

  By Design<br /><br />
		The product team believes this item works according to its intended design.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 775742 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 1/3/2013 5:36:51 PM
Access Restriction Public


It is a good practice to wipe keys and other secrets from memory after use. This practice is generally followed in .NET framework cryptography-related classes.

However, AesCryptoServiceProvider makes a copy of key and IV into temporary buffers prior to submitting them to the CryptoAPI, and never clears these temporary buffers, leaving the sensitive data in memory.

public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv)
    byte[] buffer = (byte[]) key.Clone();
    byte[] buffer2 = null;
    if (iv != null)
        buffer2 = (byte[]) iv.Clone();
    using (SafeCapiKeyHandle handle = CapiNative.ImportSymmetricKey(this.m_cspHandle, GetAlgorithmId(buffer.Length * 8), buffer))
        return this.CreateDecryptor(handle, buffer2);

Sign in to post a comment.
Posted by aaa444 on 1/17/2013 at 11:04 AM
Ironically, purely managed AES implementation, aka RijndaelManaged, does not have this problem and keys are zeroized after use, and after calling Clear/Dispose methods. The sample code shown, for example, does not leave traces of key in memory with RijndaelManaged.

It's just that this particular wrapper over CryptoAPI makes a copy of the key into byte[] buffer, via Clone(), and while it would be easy to wipe this temporary buffer by putting zeroization into try/finalize, it's not done.

Posted by Shawn [MSFT] on 1/17/2013 at 10:34 AM
Thanks for your comment. The .NET cryptography classes which are implemented in purely managed code have not been designed to wipe all traces of their keys from memory. If that level of key security is important for your use, then using an API which stores the key in a protected location, such as in a hardware cryptographic device is recommended. For example, use of the Windows CNG APIs will allow you to have stronger control over the key escaping into memory.

-Shawn Farkas [MS]
Posted by Microsoft on 1/8/2013 at 11:58 PM
Thank you for submitting feedback on Visual Studio and .NET Framework. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by aaa444 on 1/4/2013 at 7:58 PM
Or, you can use WinDbg, load the dump in there, and run command

s -b 0x00000000 L?0xffffffff 05 10 07 1e 05 18 07 26
Posted by aaa444 on 1/4/2013 at 7:37 PM
In this particular situation you can just search the .dmp file with the hex editor of your choice ( like ) for a sequence of key bytes in one of the memory blocks.

In userdump created with the code above, using AesCryptoServiceProvider, the key will be found at least once.

If you change AesCryptoServiceProvider to RijndaelManaged, and create another dump, no key bytes will be found.
Posted by Microsoft on 1/4/2013 at 1:48 AM
Hi aaa444, i'm sorry i'm not familiar with this issue, i need your help. I have created the dmp file, but i don't know how to check the existent of the key. I debuged the dmp file in VS and then opened debug->windows->memory->memory1 windows. After i typed the key in the address, VS shows "Unable to evaluate the expression. ". Is this way right?
Posted by Microsoft on 1/3/2013 at 5:50 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(