SecureString to Byte[] C#

inixsoftware picture inixsoftware · Aug 23, 2013 · Viewed 8.2k times · Source

How would I get a byte[] equivalent of a SecureString (which I get from a PasswordBox)?

My objective is to write these bytes using a CryptoStream to a file, and the Write method of that class takes a byte[] input, so I want to convert the SecureString to the byte[] so I can use in with a CryptoStream.

EDIT: I don't want to use string as it defeats the point of having a SecureString

Answer

Eric Lloyd picture Eric Lloyd · Aug 7, 2014

Assuming you want to use the byte array and get rid of it as soon as you're done, you should encapsulate the entire operation so that it cleans up after itself:

public static T Process<T>(this SecureString src, Func<byte[], T> func)
{
    IntPtr bstr = IntPtr.Zero;
    byte[] workArray = null;
    GCHandle? handle = null; // Hats off to Tobias Bauer
    try
    {
        /*** PLAINTEXT EXPOSURE BEGINS HERE ***/
        bstr = Marshal.SecureStringToBSTR(src);
        unsafe
        {
            byte* bstrBytes = (byte*)bstr;
            workArray = new byte[src.Length * 2];
            handle = GCHandle.Alloc(workArray, GCHandleType.Pinned); // Hats off to Tobias Bauer
            for (int i = 0; i < workArray.Length; i++)
                workArray[i] = *bstrBytes++;
        }

        return func(workArray);
    }
    finally
    {
        if (workArray != null)
            for (int i = 0; i < workArray.Length; i++)
                workArray[i] = 0;
        handle.Free();
        if (bstr != IntPtr.Zero)
            Marshal.ZeroFreeBSTR(bstr);
        /*** PLAINTEXT EXPOSURE ENDS HERE ***/
    }
}

And here's how a use case looks:

private byte[] GetHash(SecureString password)
{
    using (var h = new SHA256Cng()) // or your hash of choice
    {
        return password.Process(h.ComputeHash);
    }
}

No muss, no fuss, no plaintext left floating in memory.

Keep in mind that the byte array passed to func() contains the raw Unicode rendering of the plaintext, which shouldn't be an issue for most cryptographic applications.