Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / operating-systems / Windows

Secure Strings

4.20/5 (3 votes)
8 Nov 2011CPOL2 min read 24.4K  
Use of SecureString class in .NET

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):

C#
using System;
using System.Security;
using System.Runtime.InteropServices;
public static class Program {
public static void Main() {
	using (SecureString ss = new SecureString()) {
		Console.Write("Please enter password: ");
		while (true) {
			ConsoleKeyInfo cki = Console.ReadKey(true);
			if (cki.Key == ConsoleKey.Enter) break;
			// Append password characters into the SecureString
			ss.AppendChar(cki.KeyChar);
			Console.Write("*");
		}
		Console.WriteLine();
		// Password entered, display it for demonstration purposes
		DisplaySecureString(ss);
	}
	// After 'using', the SecureString is Disposed; no sensitive data in memory
}

// This method is unsafe because it accesses unmanaged memory
private unsafe static void DisplaySecureString(SecureString ss) {
	Char* pc = null;
	try {
		// Decrypt the SecureString into an unmanaged memory buffer
		pc = (Char*) Marshal.SecureStringToCoTaskMemUnicode(ss);
		// Access the unmanaged memory buffer that
		// contains the decrypted SecureString
		for (Int32 index = 0; pc[index] != 0; index++)
		Console.Write(pc[index]);
	}
	finally {
		// Make sure we zero and free the unmanaged memory buffer that contains
		// the decrypted SecureString characters
		if (pc != null)
		Marshal.ZeroFreeCoTaskMemUnicode((IntPtr) pc);
	}
}
}

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.

http://msdn.microsoft.com/en-us/library/system.security.securestring.aspx

History

  • 6th November, 2011 – Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)