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.