SecureString in .Net V2
I have been playing with the SecureString class in .Net V2 lately (System.Security.SecureString). Its one of those incremental changes to the framework that is nice to have.
Briefly, the SecureString holds a strings contents in memory in encrypted form (using DPAPI). A standard string is held in memory and is often used to contain sensitive data like connection strings, credit card details, whatever. The standard string is immutable meaning once allocated, you can't overwrite it so there is no easy way to clear it. The garbage collector can move this around (i.e. its not pinned), potentially keeping many copies of the string in memory at any one time. These memory contents can make their way into SWAP files, where its a lot easier to be found.
So, the SecureString is 'pinned' so the GC cannot move it around, its contents are encrypted using DPAPI, so whether its in memory or the SWAP file, you cannot examine its contents easily. It is mutable, so it can also be 'cleared' or zero'ed out effectively erasing its contents from memory, not simply marking it for collection.
Sounds ok, and you'd only use it in certain situations, but I was curious as to what the cost is.
Ease of use is an obvious cost (although I am more concerned with performance right now). The SecureString requires you to add characters into it, rather than assigning a string, for obvious reasons. Once you construct a string object, its in memory, and the advantage of secure string is useless as its already in memory in plain text. So the code might be:
SecureString secret = new SecureString();
secret.AppendChar('H');
secret.AppendChar('i');
Also retrieving that string later involves some interop marshalling. The code below shows an example:
IntPtr ptr = Marshal.SecureStringToBSTR(secret);
string myRegularString = Marshal.PtrToStringUni(ptr));
So the code is a little more, nothing too hairy though. I wondered about the performance cost of this though. Not that performance is going to be a real issue as I would not envision its use for a large number of string operations, but I was curious anyway. I wrote some code to add a standard string obejct to a StringBuilder 10000 times, and to add the contents of a SecureString (containing the same text as the standard string) to a StringBuilder the same amount of times (10000). The results are below:
As you would expect, a pretty reasonable hit, given the encryption and marshalling that needs to occur.