.NET Secure String

Today we are going to take a look in the System.Security namespace to learn how to create secure strings in .NET Framework. The standard .Net string is stored in managed memory giving you no way to control when it is destroyed. This is not ideal for applications that need to work with sensitive information such as Social Security Numbers or Credit Card numbers. If your application works with this type of data it might be worth taking some time to evaluate the SecureString class.

The SecureString class will automatically encrypt the data when it is stored in memory. It also implements the IDisposable interface so that you can control when the string is destroyed. Even better than just freeing memory, the Dispose method writes binary zeros to the allocated memory before it is freed. This ensures that the string is not readable after it’s memory is done being used.

Another feature of SecureString is the string created is mutable until you tell the string to be read-only. This means it can be manipulated over time, where as the standard string class is immutable. Since it is not related to the standard string class it does not have some of the same methods to compare or convert the string. The documentation states this is to help prevent any accidental/malicious exposure and suggests using the Marshal class.

To use it:

//  Could take input from console or another api
var secureString = new SecureString();

secureString.AppendChar('s');
secureString.AppendChar('e');
secureString.AppendChar('c');
secureString.AppendChar('u');
secureString.AppendChar('r');
secureString.AppendChar('e');

IntPtr secureStringPointer = IntPtr.Zero;
try
{
  // copy to unmanaged memory and decrypt
  secureStringPointer = Marshal.SecureStringToGlobalAllocUnicode(secureString);

  // use the pointer with a function like Win32 API logon
  // Full example at https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.securestringtoglobalallocunicode(v=vs.110).aspx
  // returnValue = LogonUser(userName, domainName, secureStringPointer, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
}
finally
{
  Marshal.ZeroFreeBSTR(secureStringPointer);
}

More Information

A few .NET Api’s that use the SecureString class are:

You can find out more information on the MSDN SecureString page. The original announcements on the the .NET Security Blog has good information on why SecureString is designed the way it is.

I did use it in some the samples but you will find that I don’t have to many real world examples. From my current understanding, taking the input from a string or moving the the value into a string when done would defeat the purpose since we would be giving up control over the value to the Garbage Collector. Using existing API’s such as the password input from a WPF form and then encrypting a X509 Certificate seems to be one of the few useful scenarios available today. If you have any good examples on how to use this class I would love to get some feedback.

Comments

comments powered by Disqus