As others have already answered, the contents of SecureString
are encrypted using DPAPI, so the keys aren't stored in your application, they're part of the OS. I'm not 100% positive, but I would assume that SecureString
uses a user-specific key, so that even if another process gains access to the block of memory, it would have to be running under the same credentials in order to simply decrypt the content using the DPAPI. Even if not, the machine key (in theory) prevents the string from being readily decrypted if transferred to another system.
More important with SecureString
is how & when you use it. It should be used to store string data that needs to be retained in memory for "extended" periods of time, but which are not frequently needed in their decrypted form. At some point, you're going to have to decrypt it into a regular old System.String
, or a System.Char[]
. This is when it's most vulnerable in memory. If you do this too often, then you have multiple copies of the decrypted string floating around in memory waiting to be collected.
As a general rule, if I'm reading encrypted data (say login credentials) that I need to retain for infrequent use (PayPal or Amazon API interaction, for instance), then I store/cache those credentials as SecureString
, then decrypt it as-needed only long enough to make the web service calls, and ensure that the lifespan of any decrypted copy is only a few lines of code.
It's probably also wise to use critical blocks or similar to hint to the CLR that it should not context-switch while the decrypted string is in use, to improve the chances that any decrypted copies are collected before the memory is cached or swapped.