Assuming you want to use an array of bytes and get rid of it as soon as you are done, you should encapsulate the whole operation so that it clears itself:
public static T Process<T>(this SecureString src, Func<byte[], T> func) { IntPtr bstr = IntPtr.Zero; byte[] workArray = null; GCHandle handle = GCHandle.Alloc(workArray, GCHandleType.Pinned); try { bstr = Marshal.SecureStringToBSTR(src); unsafe { byte* bstrBytes = (byte*)bstr; workArray = new byte[src.Length * 2]; 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); } }
And this is what the usage example looks like:
private byte[] GetHash(SecureString password) { using (var h = new SHA256Cng())
No mousse, no fuss, no plain text in mind.
Keep in mind that the byte array passed to func() contains raw Unicode rendering of clear text, which should not be a problem for most cryptographic applications.
Eric Lloyd
source share