So, you know everything about text, right?–part X
This is becoming a large series on strings…the good news is that there are still several interesting things to say about them, so this will be another “text post”. Today, we’ll take a quick look at how we can secure a string. As you know, there are lots of times where a string contains sensitive data (ex.: passwords). By default, string contents are saved in a char array maintained in memory which can be accessed by some other “naughty” code which might be snooping around the process address space of an application.
If this kind of behavior bothers you (or if you’re developing an app where sensitive data must conforms to more tight security rules), then you should probably rely on the SecureString type. SecureString instances store their string contents as encrypted chars on an unamanged memory block (so that the garbage collector isn’t aware of that memory). Currently, you can insert (instance method InsertAt), append (AppendChar), set (SetAt)or remove (RemoveAt) a char from encrypted array maintained in that unmanaged block. To illustrate its use, lets look at some code:
In the previous snippet, we use the ReadKey to read key presses from a console app. Each key is added to the SecureString instance until the user presses the ENTER key. Notice that the instance methods used for manipulating the secure string stored chars’ need to perform several steps which don’t really “perform” very well. The desired operation is always preceded by a decryption and followed by an encryption to ensure that the internal chars are “safe” again. As you can see, making lots of instance method calls to a SecureString instance might have a negative impact in the performance of your app.
Even though the previous snippet doesn’t show it, the SecureString class implements de IDiposable interface. By doing that, you can easily destroy the unmanaged buffer when you’re done with a SecureString instance (btw, the unmanaged buffer is zeroed before being released). And that’s why you should always dispose of SecureString instances when you’re done with them!
If you look at the API of the SecureString class, you’ll notice that it doesn’t really provide you with an easy way to recover a string instance from it. And that’s by design…and it’s really a good thing If, by any chance, you think that you need to interact with the SecureString string, then don’t!
If you really really really…really need to do that, then the solution is to use the Marshal class. It also means writing unmanaged code, so get ready for seeing some pointers in action (and compiling your project with the /unsafe option):
Nasty…to be honest, I really didn’t miss having to use all those pointers…but that’s what is needed
to read the chars stored by a SecureString instance. Once again, don’t do this in real world projects!
Unfortunately, SecureString support is limited in the current API of the classes defined by the .NET framework. You can use them with certificates (X509Certificate class), when constructing an event log (EventLogSession class) or when using the PasswordBox control…and that’s pretty much it….I’m hopping to see them used in more places in future releases of the framework, but for now, that’s all we’ve got (I probably missed one or two classes, but I guess that’s all).
And I think this sums it up quite nicely. Stay tuned for more!