.NET’s SecureString

I’m investigating various security based topics at the moment. Whilst I have dabbled in security in the past I do not class myself an expert on the subject, hence these posts may be fairly basic.

Background

I’m doing some coding that requires a level of security around data (specifically strings) which is simply not available using the String class.

The String class has a couple of properties which make it less than secure

  • The string is stored in memory as plain text
  • The disposal of memory is non deterministic and hence can remain in memory long after it’s usage has been completed

Obviously if we were to store a password in a string we can use tools such as WinDbg to dump memory and ultimately locate all instances of the password strings. Sure it might take a bit of time, but ultimately we’d find the password as plain text.

A solution?

TL;DR SecureString is only really secure until you need to get at the string, this isn’t a solution to 100% security but may help in certain situations, not least for situations where you want to pass a string between methods.

SecureString is a .NET class which is totally unrelated to the String class and it’s aim is to fix the security issues which exist for the String class, so

  • The SecureString may be encrypted within memory, on the MS website it suggests this is dependent upon the underlying OS
  • We can dispose of a SecureString in a deterministic way, i.e. calling the Dispose method or worse case garbage collected

To store some characters in a SecureString we have to append characters, like this

public static SecureString ToSecureString(string data)
{
   var secure = new SecureString();
   foreach (var c in data)
   {
      secure.AppendChar(c);
   }
   secure.MakeReadOnly();
   return secure;
}

We can also assign characters via a constructor override which takes a char* and length argument.

To turn a SecureString back into a String we can use

public static string ToString(SecureString secureString)
{
   var ptr = Marshal.SecureStringToBSTR(secureString);
   try
   {
      return Marshal.PtrToStringBSTR(ptr);
   }
   finally
   {
      Marshal.ZeroFreeBSTR(ptr);
   }
}

If, you come from a COM and C++ background you’ll recognize the BSTR’s.

In this code we get a pointer to the unmanaged BSTR from the SecureString then we use the pointer to create a String object. In the finally clause we zero out and release the memory that the BSTR used, ensuring that our password (or whatever) is both cleared and then removed from memory.

You might now be questioning what use the SecureString really is, if we ultimately convert whatever it’s storing too and from a String.

Ofcourse what you really need to do is store data which might be around for a while in the SecureString and preferably rarely convert them to Strings.

Secure input

Control-wise, WPF contains a SecurePassword property on the PasswordBox to allow input to be turned into a SecureString. Hence we can use this to take user input and store “secure” from input until the point we need to use it.

See also

Comparing secure strings in .NET