If you are looking for a smart way to encrypt/decrypt sensitive data in memory in order to make them unreadable even in malicious memory dumps, maybe you need to use the ProtectedMemory class (namespace System.Security.Cryptography). This class is a managed wrapper included in the DPAPI (Data Protection API) and it works in the same way as ProtectedData (a similar class indeed used to persist encrypted strings in file/database): it exposes two static methods, Protect and Unprotect, which allow you to encrypt/decrypt strings in memory. The only requirement you have to consider in order to avoid a CryptographicException is about using 16-bytes blocks for computing encrypted/decrypted data. For example, the following code shows how to protect/unprotect a sensitive string in memory during a process execution:
Here the output:
Before Protect: xxxxxxxxxxxxxxxx
After Protect: 7j??‼8y_??PQ<?¶-
After Unprotect: xxxxxxxxxxxxxxxx
Some further considerations:
- The Protect()/Unprotect() method works directly on the original data, not on a copy. So, we don’t need to explicitly destroy our sensitive strings after the use.
- Many people use SecureString, a more intuitive class using ProtectedMemory to automatically encrypt strings. A SecureString can be modified till the MakeReadOnly() method call and can be programmatically disposed. Finally, its MemoryProtectionScope is SameProcess: a SecureString can’t be used in CrossProcess and SameLogon scenarios, in which there’re multiple applications running in different processes (CrossProcess) and allowing data encryption/decryption to the same Windows user (in particular cases, consider the impersonation technique).
- I’ve noticed some strange behaviours by randomly analyzing the memory dump file after invoking the Protect() method on a string: sometimes the text I’d like to protect appears as clear text…mmmm…. Does Windows operate a swap on file system before data encryption? If this is a possibility, are my efforts unuseful?