Per MSDN:
Represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed. This class cannot be inherited.
Storing any sensitive data like passwords etc in the standard System.String can be a potential threat to the data for the following reasons:
>> It is stored on the Managed Heap and is not pinned in the memory, so the garbage collector can move it around at will leaving several copies in memory. The code will not know that this has happened, and even if it could figure out that the string was moved, there is no way to clear out the other copies. Instead we have to wait for the CLR to allocate another object where the sensitive data is so that the memory gets erased.
>> It's not encrypted, so anyone who can read process's memory will be able to see the value of the string easily. Also, if the process gets swapped out to disk, the unencrypted contents of the string will be written to the swap file.
>> It's not mutable, so whenever it is modified, there will be the old version and the new version both in memory
>> Since it's not mutable, there's no effective way to clear it out when you're done using it
Hence, .NET 2.0 introduced a new class under System.Security namespace called SecureString, that can be used in place of standard Strings to store sensitive values.
Using SecureString eliminates the above mentioned issues as:
>> The SecureString is not stored in the managed heap while standard strings are and therefore it will not be replicated to multiple locations in memory.
>> SecureStrings are stored in an encrypted form. They need to be decrypted when they are used. this period of decryption can be kept as small as possible. So even if the process is swapped out to disk while the string is encrypted, the plaintext will not end up in the swap file.
>> The keys used to encrypt the string are tied to the user, logon session, and process. This means that any minidumps taken of the process will contain secure strings which are not decryptable.
>> SecureStrings are securely zeroed out when they're disposed of. System.Strings are immutable and cannot be cleared when you've finished with the sensitive data
create a SecureString, you append one character at a time:
System.Security.SecureString secString = new System.Security.SecureString();
secString.AppendChar(p);
secString.AppendChar('a');
secString.AppendChar('s');
secString.AppendChar('s');
secString.AppendChar('w');
secString.AppendChar('d');
When the string contains the data you want, you can make it immutable and uncopyable by calling the MakeReadOnly method:
secString.MakeReadOnly();
To read the secure value, use the SecureStringToBSTR() method as follows:
IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(secString);
string sDecrypString = System.Runtime.InteropServices.Marshal.PtrToStringUni(ptr);
The garbage collector will remove SecureStrings when they're no longer referenced, but you
can dispose of a SecureString by using the Dispose() method:
secString.Dispose();