I am implementing SecureString in a project. After reading up on it and seeing lots of examples basically doing the same thing, I keep thinking that something is wrong.
Take for example the following code:
public static string ToUnsecureString(this SecureString secureString)
{
if(secureString == null)
throw new ArgumentNullException("secureString");
IntPtr unmanagedString = IntPtr.Zero;
try
{
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
return Marshal.PtrToStringUni(unmanagedString);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}
}
It's great to have the data secured, but what's really the point when in the end it just gets set to a standard string again?
I know you can just store the password in a char[]
and then zero it out after creating the SecureString
, but what am I supposed to do when retrieving the string? I did not see a way to retrieve it as a char[]
and wouldn't just calling .ToCharArray()
still leave the string that Marshal.PtrToStringUni(...)
returned in memory?
Am I just missing something extremely fundamental? Thanks.
You're right -- using the contents of a
SecureString
in managed code is pretty silly. However, for P/Invoke APIs such as the Windows Credential API, it's just the thing for keeping your password away from prying eyes.Another possibility is to call
Marshal.SecureStringToBSTR()
and do all your processing in unmanaged code, you can still maintain some semblance of security.