Ayende @ Rahien

It's a girl

System.Security.SecureString annoyances

SecureString has exactly one purpose. Take information from the user and pass it to unmanaged function. anything else that you would try to do with it seems to be incredibly hard to do.

I wanted to extend Rhino Service Bus so a message that contained SecureString members would be automatically encrypted on the wire. It seemed like a nice & easy option to provide field level security for messages. However, it doesn’t seem to be a viable option, because working with SecureString is such an awkward task. I have created a WireEncryptedString class and I’ll just use that instead. Grr….

Comments

Mihailo
01/14/2009 05:57 PM by
Mihailo

Hi Oren,

SecureString is ment to be used only locally, for storing sensitive information in memory while the application is running, and it is its sole purpose. Encryption/decryption is machine specific and even if you could send it over wire you wouldn't be able to decrypt it on other machine.

Cheers,

Mihailo

Ayende Rahien
01/14/2009 06:01 PM by
Ayende Rahien

I know that, I wanted to be able to use that as a "tag" for the serialization format to be able to use that for knowing that it needs to be encrypted.

The problem is that it has so many limitations on its use that it is not worth even trying.

Ayende Rahien
01/14/2009 07:22 PM by
Ayende Rahien

Alberto,

the problem isn't the actual encryption, the problem is that SecureString is so heavily limited as to be utterly and completely useless.

Adam Tybor
01/14/2009 09:07 PM by
Adam Tybor

Extension Methods to the rescue.... They seem pretty silly to me, but it was a recent requirement to use SecureStrings for some stuff.

public static SecureString ToSecureString(this string value)

{

  var secureString = new SecureString();

  if (!string.IsNullOrEmpty(value))

  {

    foreach (char c in value)

    {

      secureString.AppendChar(c);

    }

  }


  secureString.MakeReadOnly();

  return secureString;

}


public static void WorkWith(this SecureString secureString, Action

<string work)

{

  IntPtr bzPtr = Marshal.SecureStringToBSTR(secureString);

  try

  {

    work(Marshal.PtrToStringBSTR(bzPtr));

  }

  finally

  {

    Marshal.ZeroFreeBSTR(bzPtr);

  }

}


public static void WorkWith(this SecureString secureStringA0, SecureString secureStringA1, Action

<string,> work)

{

  IntPtr bzPtrA0 = Marshal.SecureStringToBSTR(secureStringA0);

  IntPtr bzPtrA1 = Marshal.SecureStringToBSTR(secureStringA1);

  try

  {

    work(Marshal.PtrToStringBSTR(bzPtrA0), Marshal.PtrToStringBSTR(bzPtrA1));

  }

  finally

  {

    Marshal.ZeroFreeBSTR(bzPtrA0);

    Marshal.ZeroFreeBSTR(bzPtrA1);

  }

}
configurator
01/14/2009 09:10 PM by
configurator

@Adam: You do realize you're defeating the purpose of a SecureString when you do that, right? The entire idea behind SecureString is that the complete string can never be kept in memory - and if you make it from a string the complete string is already in memory.

Adam Tybor
01/14/2009 09:15 PM by
Adam Tybor

@configurator... Yes I do, hence my comment "They seem pretty silly to me, but it was a recent requirement to use SecureStrings for some stuff."

I don't make the requirements and I won't turn every little battle into a war. The client is aware that "ThisIsAlreadyFubar".ToSecureString() defeats the purpose but it seems they still want it.

Ayende Rahien
01/14/2009 09:42 PM by
Ayende Rahien

That is the same issue that I arrived at, and as a result I am not using it.

Comments have been closed on this topic.