Using SecureString

2019-01-31 17:28发布

问题:

Can this be simplified to a one liner? Feel free to completely rewrite it as long as secureString gets initialized properly.

SecureString secureString = new SecureString ();
foreach (char c in "fizzbuzz".ToCharArray())
{
    secureString.AppendChar (c);
}

回答1:

You could use Linq:

"fizzbuzz".ToCharArray ().ToList ().ForEach ( p => secureString.AppendChar ( p ) );


回答2:

Just use NetworkCredential. It has the conversion logic built-in.

SecureString ss = new NetworkCredential("", "fizzbuzz").SecurePassword;

As others have noted, all of these techniques strip the security benefits of SecureString, but in certain situations (such as unit tests) this may be acceptable.

Update:

As noted in the comments, NetworkCredential can also be used to convert a SecureString back to a string.

string s = new NetworkCredential("", ss).Password;


回答3:

Apart from using unsafe code and a char*, there isn't a (much) better way.

The point here is not to copy SecureString contents to/from normal strings. The constant "fizzbuzz" constant is the security leak here.



回答4:

Slight improvement on Sascha's answer replacing the lambda with a method group

"fizzbuzz".ToCharArray().ToList().ForEach(ss.AppendChar);


回答5:

var s = "fizzbuzz".Aggregate(new SecureString(), (ss, c) => { ss.AppendChar(c); return ss; });


回答6:

Here is a how NetworkCredential class from .NET doing it:

SecureString secureString;
fixed (char* chPtr = plainString)
  secureString = new SecureString(chPtr, plainString.Length);

Ugly but probably the most efficient.



回答7:

Since SecureString utilizes the IDispose interface. You could actually do it like this.

SecureString secure = new SecureString();
foreach(var character in data.ToCharArray())
    secure.AppendChar(character);

Essentially the data would be a parameter.

If you utilize the using to help alleviate resources; you'll want to be careful about the scope. But this may be a beneficial alternative, depending on usage.

Update:

You could actually do a full method signature:

public static SecureString ConvertStringToSecureString(this string data)
{
     var secure = new SecureString()
     foreach(var character in data.ToCharArray())
         secure.AppendChar(character);

     secure.MakeReadOnly();
     return secure;

}

For the decryption you would want to do:

public static string ConvertSecureStringToString(this SecureString data)
{
     var pointer = IntPtr.Zero;
     try
     {
          pointer = Marshal.SecureStringToGlobalAllocUnicode(data);
          return Marshal.PtrToStringUni(pointer);
     }
     finally
     {
          Marshal.ZeroFreeGlobalAllocUnicode(pointer);
     }
}

The following article will give you some additional information as well.



回答8:

least amount of code because .ToList() is not required for this:

Array.ForEach("fizzbuzz".ToCharArray(), secureString.AppendChar);