Getting and Setting a SecureString in .NET 2.0

SecureString Class
A nice new addition to the .NET 2.0 Framework is the SecureString class making it safe to store sensitive information in memory (e.g. passwords, connection strings). This class takes care of encrypting this information but the class does not provide a very straightforward method for getting and setting its value.

Since the actual value of the string is NOT stored in the memory space of your process it is not really a "managed" value so a bit of marshaling is required to work with it.

Setting a SecureString’s value
Fortunately, it is rather easy to set the value of a SecureString … but it has to be character by character. I assume the reason for this is because you really should not be using any transient/temporary variable to load the data into the SecureString. That would pretty much defeat its purpose. However, there will come a time when you want to set the value of the SecureString FROM another string. That much is simple:

SecureString securePassword = new SecureString();
string insecurePassword = "password";

foreach(char passChar in insecurePassword.ToCharArray()) {
    securePassword.AppendChar(passChar);
}



The above code simply iterates through the characters in the string and appends them to the SecureString.

Getting a SecureString’s value
It is as difficult, however, to retrieve the value from a SecureString as it was simple to set it. Since the value of the SecureString is not in the application’s process space your code has to interact with it via a pointer to a BSTR:

IntPtr passwordBSTR = default(IntPtr);

try {
    passwordBSTR = Marshal.SecureStringToBSTR(securePassword);
    insecurePassword = Marshal.PtrToStringBSTR(passwordBSTR);
} catch {
    insecurePassword = "";
}

This code uses the Marshal static class to retrieve the value of the SecureString into a BTRS and returns its pointer. Next, again using the Marshal class to reads the BSTR into a managed string vairable to be used at will.

Is this secure?
No … not really. It should be apparent by now that you are taking the value out of a secure, encrypted memory location and putting it right back into an insecure, unencrypted location.

Advertisements

3 thoughts on “Getting and Setting a SecureString in .NET 2.0

  1. Apparently, SecureString is using DPAPI, which was the recommended practice noted by Microsoft a few years ago as the best method for securing things like passwords.  It stores the password in protected memory space unlike a regular managed string.  I recently ran across this article which gives some more background on the new security features accessible in .NET 2.0:
    http://msdn.microsoft.com/msdnmag/issues/06/00/SecurityBriefs/default.aspx
    Enjoy!

  2. SecureString should never be fed with a managed string, let alone copying it back out to one, since managed strings live on the managed heap, and can be copied all over the place as the GC moves the objects around. Ideally, you intercept keystrokes and feed the SecureString one character at a time, since a char is a ValueType and lives on the stack, which will be overwritten when the scope is exited. Of course, if it isn’t boxed by putting it in an object reference somehow. Adding to an IList<char> should also work, since the runtime keeps these allocations on the stack and out of the heap.
     
    Keeping it out of the managed heap is why the framework designers make it so hard to do, and you can only get it out as a BSTR, memory which you (can) control.

  3. Rory … I could not agree more with what you are saying.  Even creating the secure string character by character there is certainly a hole there.  I suppose I am questioning the use for a SecureString in a .NET application.  I would certainly rule it out in a Web application even if you were getting creative with sending a character over the wire one-at-a-time.   

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s