Secure Strings

Introduction

Often, String objects are used to contain sensitive data such as a user’s password or creditcard information. Unfortunately, String objects contain an array of characters in memory, and if some unsafe or unmanaged code is allowed to execute, the unsafe/unmanaged code could snoop around the process’s address space, locate the string containing the sensitive information, and use this data in an unauthorized way. Even if the String object is used for just a short time and then garbage collected, the CLR might not immediately reuse the String object’s memory (especially if the String object was in an older generation), leaving the String’s characters in the process’s memory, where the information could be compromised. In addition, since strings are immutable, as you manipulate them, the old copies linger in memory and you end up with different versions of the string scattered all over memory.

Background

Some governmental departments have stringent security requirements that require very specific security guarantees. To meet these requirements, Microsoft added a more secure string class to the FCL: System.Security.SecureString.

Using the Code

When you construct a SecureString object, it internally allocates a block of unmanaged memory that contains an array of characters. Unmanaged memory is used so that the garbage collector isn’t aware of it.

These string’s characters are encrypted, protecting the sensitive information from any malicious unsafe/unmanaged code. You can append, insert, remove, or set a character in the secure string by using any of these methods: AppendChar, InsertAt, RemoveAt, and SetAt. Whenever you call any of these methods, internally, the method decrypts the characters, performs the operation in place, and then re-encrypts the characters. This means that the characters are in an unencrypted state for a very short period of time. This also means that the performance of each operation is less than stellar, so you should perform as few of these operations as possible.

Here is some sample code demonstrating how to initialize and use a SecureString (when compiling this, you’ll need to specify the /unsafe switch to the C# compiler):

The SecureString class implements the IDisposable interface to provide an easy way to deterministically destroy the string’s secured contents. When your application no longer needs the sensitive string information, you simply call SecureString’s Dispose method. Internally, Dispose zeroes out the contents of the memory buffer to make sure that the sensitive information is not accessible to malicious code, and then the buffer is freed.

Points of Interest

In version 4 of the .NET Framework, you can pass a SecureString as a password when:

Working with a cryptographic service provider (CSP) - See the System.Security.Cryptography.CspParameters class.

Starting a new process under a specific user account - See the System.Diagnostics.ProcessStartInfo classes.

Constructing an event log session. See the System.Diagnostics.Eventing.Reader.EventLogSession class.

Using the System.Windows.Controls.PasswordBox control. See this class’s SecurePassword property.

Share

About the Author

I spent some time working as a programmer and computer developer for several IT companies. I gained a lot of knowledge and experience in the process, and met some very supportive people in the industry. In May 2000' I joined LBS College for Higher studies.

I enjoyed my studies as much as academic studies can be enjoyed. I feel that I depend my understanding of computers because of them. The LBS College gives his students a high level of studying, but my main problem with it is that its tests are sometimes completely out of sync with the material that is learned, too long and/or too hard, and so students receive low grades and are frustrated. This is especially demotivating considering the fact that studying there is a lot of work.

Comments and Discussions

Don't get me wrong. I see the value of having a secure string. What I am a confused at is how this prevents there being sensitive strings in the processes address space.

For instance, if we are prompting for a password from the user and we would like to save that data for later use you are saying we should use SecureString, but we need to collect that data from the user. To do this and to store the retrieved value we collected, we need to use the controls provided by the .NET Framework, such as ASP:TextBox or Windows TextBox (both of which can be set in password mode), which use String and not SecureString. So to set the value of the SecureString at runtime doesn't that mean that somewhere in memory we have that sensitive data sitting in a Standard String, such as txtPassword.Text? Since the string exists in application memory because of the use of a control, it defeats the purpose of SecureString. And how could we otherwise get the data into a SecureString? LINQ doesn't use SecureString does it? Which means we can't get a SecureString from a database (it would be read as a String). Unless you populate it one character at a time, which wouldn't happen, you can never guarantee that there won't be a copy of the sensitive data in memory.

The WPF PasswordBox is the only instance where I see it would be of any benefit, since it uses SecureString. Perhaps I am missing something here. I don't see much of an advantage to use SecureString.

Yes, somewhere you are correct. Until Microsoft doesn’t add “SecurePassword” property to its legacy TextBox control, SecureString is not very useful. But I am sure they will doin near future since they have given thisin WPF.
Thanks for showing interest in my article.