Abstract:
Storing sensitive data in a String object makes it impossible to reliably purge the data from memory.
Explanation:
Sensitive data (such as passwords, social security numbers, credit card numbers, encryption keys etc.) stored in an unmanaged memory buffer can be leaked if it is not explicitly zeroed out, even if it is freed. The unmanaged buffers are often not encrypted by default, so anyone that can read the process' memory will be able to see the contents. Furthermore, if the process' memory gets swapped out to disk, the unencrypted contents of the string will be written to a swap file. In the event of an application crash, a memory dump of the application might reveal sensitive data.
Example 1: The following example creates a symmetric key before using it.
public static void CreateAndUseEncryptor()
{
SymmetricAlgorithm aesAlgorithm = SymmetricAlgorithm.Create("AES");
aesAlgorithm.GenerateKey();
aesAlgorithm.GenerateIV();
Encrypt(aesAlgorithm);
}
Since neither CreateAndUseEncryptor() nor Encrypt() run Clear() or Dispose(true) on the SymmetricAlgorithm object, the key and initialization vector (IV) will not be zeroed out in memory.
Recommendations:
After creating an initialization vector (IV) or encryption key, it is absolutely necessary to make sure they are cleared from memory by either running Clear() or Dispose(true) on the object.
Example 1: The following method generates a key and an IV, then uses a finally block to make sure the key and IV are zeroed out in memory.
public static void CreateAndUseEncryptor()
{
SymmetricAlgorithm aesAlgorithm = null;
try
{
aesAlgorithm = SymmetricAlgorithm.Create("AES");
aesAlgorithm.GenerateKey();
aesAlgorithm.GenerateIV();
Encrypt(aesAlgorithm);
}
finally
{
if (aesAlgorithm != null)
{
aesAlgorithm.Clear();
}
}
}
Example 2: The following example uses a using-block that automatically calls Dispose(), which zeroes out the key and IV in memory.
public static void CreateAndUseEncryptor()
{
using (SymmetricAlgorithm aesAlgorithm = SymmetricAlgorithm.Create("AES"))
{
aesAlgorithm.GenerateKey();
aesAlgorithm.GenerateIV();
Encrypt(aesAlgorithm);
}
}
In the various symmetric, asymmetric, and hash algorithm implementations, Dispose() is overridden by calling Clear() then Dispose(true)
0 comments:
Post a Comment