One of the trickier aspects of development is working with sensitive data such as social security numbers, employee identification numbers, and so forth.
The .NET Framework includes cryptography functionality, but it is often overkill for smaller applications. Beginning with .NET Framework 2.0, the SecureString class is available to easily hold encrypted data in memory. Here are details about using the SecureString class.
When you should use the SecureString class
You may be wondering why the SecureString class is necessary when the basic String class is readily available. The problem lies in the design of the String class. For instance, if you have an instance of the String class that contains a person's social security number, you will want to securely store it during application processing to keep it from prying eyes.
The key issue is securely storing text as the String class stores it as plain text. Discovering where the data will be stored requires some understanding of .NET strings. .NET strings are immutable; that is, every change to the string value creates a new string in memory. Consequently, there are various copies of sensitive data in memory that may be accessed by less than scrupulous code or users.
This is not the most efficient approach and explains the existence of the StringBuilder object. You may think this is not much of a problem due to garbage collection, but memory reclamation with string is not deterministic with the .NET garbage collection. So, you should avoid the String class if the data is truly sensitive and examine other alternatives like the SecureString class.
Where to find it
You can find the SecureString class in the System.Security namespace. The Microsoft documentation describes the SecureString class as representing text that needs to remain confidential because it is encrypted in memory. The SecureString class has the following features:
- String values are encrypted when stored in memory. It utilises the Data Protection API (DPAPI), so it only works on NT-based platforms.
- The SecureString class follows the IDisposable pattern.
- The encrypted text cannot be retrieved easily; that is, there is no ToString class to quickly read the contents (no one ever said encryption was easy).
The constructor of the SecureString class is overloaded to allow you to create an instance of the class two ways, as the following list outlines:
- SecureString(): A new instance of the class is initialised with no value.
- SecureString(Char*, Int32): A new instance of the class is initialised given a subarray of Char objects and its length.
- AppendChar: Allows you to add one character to the end of the string stored by the class.
- InsertAt: Allows you to insert a character in the string at a specific position.
- RemoveAt: Allows you to remove a character from the string at a specific position.
- SetAt(int, char): Allows you to populate a character value at the specific position.
- Clear: Deletes the contents of the string value.
- Copy: Creates a copy of the string value stored in the object.
- Dispose: Releases all resources used by the object.
- Length: Returns the length of the secure string value.
- MakeReadOnly: Makes the contents of the string read-only. This is irreversible.
- IsReadOny: Signals whether the contents of the object are read-only.
With the object initialised, you may use the various methods and properties of the class to work with its contents. The following list provides an overview of the more important properties and methods available:
The following C# code creates an instance of the SecureString class and stores a data value in it.
using System;
using System.Collections.Generic;
using System.Text;
namespace SecureString {
class Program {
static void Main(string[] args) {
System.Security.SecureString ss = new System.Security.SecureString();
ss.AppendChar('T');
ss.AppendChar('e');
ss.AppendChar('c');
ss.AppendChar('h');
ss.AppendChar('R');
ss.AppendChar('e');
ss.AppendChar('p');
ss.AppendChar('u');
ss.AppendChar('b');
ss.AppendChar('l');
ss.AppendChar('i');
ss.AppendChar('c');
ss.AppendChar('.');
ss.AppendChar('c');
ss.AppendChar('o');
ss.AppendChar('m');
ss.MakeReadOnly();
Console.WriteLine(ss);
} } }
The code locks the string value with the MakeReadOnly method once the final character has been added. This means the value may not be altered. An exception is thrown if you attempt to alter the data once making it read-only. You'll notice the code simply displays the name of the class (System.Security.SecureString) when it executes. The equivalent VB.NET code follows:
Module Module1
Sub Main()
Dim ss As New System.Security.SecureString()
ss.AppendChar("T")
ss.AppendChar("e")
ss.AppendChar("c")
ss.AppendChar("h")
ss.AppendChar("R")
ss.AppendChar("e")
ss.AppendChar("p")
ss.AppendChar("u")
ss.AppendChar("b")
ss.AppendChar("l")
ss.AppendChar("i")
ss.AppendChar("c")
ss.AppendChar(".")
ss.AppendChar("c")
ss.AppendChar("o")
ss.AppendChar("m")
ss.MakeReadOnly()
Console.WriteLine(ss)
End Sub
End Module



1
Joel - 04/07/07
This example may not be secure, as the TechRepublic.com string could be found in the x86 or IL code of a crash dump via the plain-text string arguments to the AppendChar method.
I believe the AppendChar method is most suited to reading from the users Console.
» Report offensive content
2
Andy - 10/07/08
Creating a SecureString is easy but what do you do with it once you have it?
I'd like to take a SecureString, calculate it's hash, and then store the hash in a database. How can I do this? How can I convert the SecureString to a byte[] so that I can feed it into the hash method and will doing so defeat the purpose of using a SecureString to begin with?
» Report offensive content