SecureString is an un-inheritable class which resides in the System.Security namespace. It holds an encrypted string and is disposed of when you’re done using it. This class is mostly used when you want to store a piece of sensitive information in memory (e.g.: social security numbers, bank account information,…). Of course, these are normally stored in encrypted form in the database, but when you are handling a user’s request (he/she is accessing his banking records, or shopping at an online store), at some point you will need the data from the database and use it in your application.
When you want to store some sensitive information in memory, the use of a string raises some issues. It’s immutable (every time you change it a new instance of the string is created) and can’t be deleted from the computer memory at will. So if you’re done using it, the string lives on in memory until it’s cleaned up by the garbage collector. Since you don’t know when this will happen (can be seconds, hours,…) your sensitive information is readable.
Of course, SecureString holds some textual information. Do note that the text you wish to keep in the SecureString-object needs to be added char by char (or when using the constructor, a char pointer and the length as an integer).
1: string aString = "This is a string";
2: SecureString secureString = new SecureString();
3:
4: foreach (char c in aString)
5: {
6: secureString.AppendChar(c);
7: }
8:
9: Console.WriteLine(aString);
10: Console.WriteLine(secureString);
When you execute that code, you will see that the WriteLine-command using the securestring as a parameter will just give you the base.ToString() value (System.Security.SecureString). This is because SecureString doesn’t override the ToString()-method nor does it provide you with any of the methods available with the regular string-class (substring, indexOf, CompareTo, StartsWith,…)
Let’s have a look at what happens to your text when you use a SecureString. When you have assigned a value to your SecureString class, you can lock it by calling the MakeReadOnly() method. The value is encrypted using DPAPI (Data Protection API) which is the encryption layer used by Microsoft Windows. When you wish to use the value stored in the SecureString object, you will have to use the Marshal class (which can be found in the System.Runtime.InteropServices namespace). Among other things, this class provides methods for allocating unmanaged memory and copying unmanaged memory blocks. This includes methods that will convert the contents of your SecureSting object into an object of type BSTR (basic string or binary string) or a block of ANSI or Unicode memory. Just reading the memory block will only give you the binary data stored in the memory block.
1: string aString = "This is a string";
2: SecureString secureString = new SecureString();
3:
4: foreach (char c in aString)
5: {
6: secureString.AppendChar(c);
7: }
8:
9: Console.WriteLine("Reading the regulare string: "+aString);
10: Console.WriteLine("Reading the secure string: "+secureString);
11: Console.WriteLine("Reading the secure string (using Marshal.SecureStringToBSTR): " + Marshal.SecureStringToBSTR(secureString));
12: Console.WriteLine("Reading the secure string (using Marshal.SecureStringToGlobalAllocAnsi): " + Marshal.SecureStringToGlobalAllocAnsi(secureString));
13: Console.WriteLine("Reading the secure string (using Marshal.SecureStringToGlobalAllocUnicode): " + Marshal.SecureStringToGlobalAllocUnicode(secureString));
Output:

We can see that the Marshal-methods have gotten something out of the SecureString class, but we can’t do much with those things. To read this memory block in a manner which will present us with a string-representation the Marshal-class provides a PtrToStringBSTR() method. The parameter which you need to provide here is a pointer to the memory-block where your contents are stored. First, we need to create that pointer using the SecureStringToBSTR method (also provided by the Marshal class).
1: IntPtr ptrToString = Marshal.SecureStringToBSTR(secureString);
2: Console.WriteLine("Contents of ptrToString: " + ptrToString);
3: Console.WriteLine("Contents of memory at ptrToString as a string: " + Marshal.PtrToStringBSTR(ptrToString));
Output:
![clip_image002[7] clip_image002[7]](http://www.fooji.net/blog/image.axd?picture=clip_image002%5B7%5D_thumb.jpg)
When converting your SecureString object to a pointer , the needed unmanaged memory is allocated to store the string. This means you will always have to clean it up (free the pointer) when you no longer need the object. Again, the Marshal-class provides this possibility in the form of the ZeroFreeBSTR method. This ensures you that the contents of the SecureString object is in plain text only very briefly.
1: Marshal.ZeroFreeBSTR(ptrToString);
2: Console.WriteLine("Contents of memory at ptrToString as a string: " + Marshal.PtrToStringBSTR(ptrToString));
3:
4: secureString.Dispose();
ptrToString still points to the memory allocated, but the contents have been cleared and calling the PtrToStringBSTR results into an empty string. SecureString inherits from CriticalFinalizerObject. This means that the finally-block of the SecureString object is always executed (even when the thread terminates abnormally).