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);
}
You could use Linq:
"fizzbuzz".ToCharArray ().ToList ().ForEach ( p => secureString.AppendChar ( p ) );
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;
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.
Slight improvement on Sascha's answer replacing the lambda with a method group
"fizzbuzz".ToCharArray().ToList().ForEach(ss.AppendChar);
var s = "fizzbuzz".Aggregate(new SecureString(), (ss, c) => { ss.AppendChar(c); return ss; });
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.
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.
least amount of code because .ToList()
is not required for this:
Array.ForEach("fizzbuzz".ToCharArray(), secureString.AppendChar);