Michael Crosby


SecureString How To

Working with the SecureString class in .NET is fairly easy. This class allows you to keep string data encrypted in memory. Maybe you load connection strings, passwords, or financial data into memory when your application starts or loads an object so the least you can do is use the SecureString class to keep this information encrypted while the data stays in memory.

Adding your data

Adding a string content to the class is very easy.

public static void Main(string[] args)
{
    var hushhush = "Something I need to keep on the down low";

    using (var secureString = new SecureString())
    {
        foreach (var chr in hushhush.ToCharArray())
        {
            secureString.AppendChar(chr);
        }
        secureString.MakeReadOnly();
    }
    Console.ReadLine();
}

All you need to do is convert your string into a char array and append each char to the secure string. After you have finished writing all data to the secure string you will want to call the MakeReadOnly method so that the instance becomes immutable.

Getting your data back out

Now this is where things get weird. It's nice not to have a convenient method on the SecureString class to get to your data for security reasons but you actually have to work with pointers and unmanaged resources to get to the data.

Because SecureString is a sealed class I made a little extension class that adds a GetString() method for reading the string data from the class.

static class SecureStringExtensions
{
    public static string GetString(
        this SecureString source)
    {
        string result = null;
        int length = source.Length;
        IntPtr pointer = IntPtr.Zero;
        char[] chars = new char[length];

        try
        {
            pointer = Marshal.SecureStringToBSTR(source);
            Marshal.Copy(pointer, chars, 0, length);

            result = string.Join("", chars);
        }
        finally
        {
            if (pointer != IntPtr.Zero)
            {
                Marshal.ZeroFreeBSTR(pointer);
            }
        }

        return result;
    }
}

The Marshal class actually has a BSTR method for use with the SecureString. Just remember when working with unmanaged resources you will need to manually release and free the pointers that you used.

Basically if you have not worked with Marshal and pointers in C# you will have to get the pointer to the char[] from the secure string. Then we use Marshal.Copy to marshal the *char[] to our managed char[] using the length of the string. A simple string.Join and we are home free. Just remember to zero out our pointer to release the resources.

comments powered by Disqus