Wednesday, April 9, 2008

How to: Use strings in a secure manner with SecureString class

The classic System.String type doesn’t provide enough security for storing sensitive data like passwords, credit card numbers or personal information. If a String object contains sensitive information, there is a risk the information could be revealed after it is used because your application cannot delete the data from computer memory. Starting with the .NET Framework 2.0 the SecureString class is available. It was designed to provide encryption for sensitive data and other useful functions.

System.String

The most important factors that don’t recommend the System.String type as a secure type are:
  • System.String is not encrypted. Anyone who can read your process' memory will be able to see the value of the string easily. Also, if your process gets swapped out to disk, the unencrypted contents of the string will be sitting in your swap file.
  • System.String is immutable. Because of this you can not modify an existing string without create a copy of it first and you can not clear the content of a string. You may end up with several copies of your sensitive data in memory which are hard to hide from a possible attacker.
  • System.String can be moved around in memory by the Garbage Collector (GC). This happens because of the Garbage Collector's generations mechanism.
  • System.String can’t be disposed on demand. No one can predict when a specific string will be reclaimed by the Garbage Collector (GC). It is possible that some strings to survive long time after the application was closed.

The byte array workaround

Before .NET 2.0, the recommended way to handle sensitive data was to use the byte array. A byte array can be handled almost in a string manner but with some extra advantages:
  • Each byte from the byte array can be encrypted and decrypted using any encoding algorithm.
  • We can clean-up the content of it.
  • We can dispose a byte array on demand.

The SecureString class

Let’s see what are the advantages that recommend the SecureString class to be better than Sytem.String or even than the byte array method:
  • A SecureString object is similar to a String object in that it has a text value. So it helps you to write cleaner code then the byte array method.
  • The value of a SecureString object is automatically encrypted when its value is initialized or modified. It will be automatically decrypted when it will be accessed.
  • The value of a SecureString can be modified until your application marks it as read-only. You'll find AppendChar(), InsertAt(), RemoveAt(), and SetAt() methods as well as a Length property.
  • The value of a SecureString can be deleted from computer memory by either your application or the .NET Framework Garbage Collector. This includes clearing the entire content.
  • The Garbage Collector (GC) will not move the encrypted string around in memory, so you never have to worry about multiple copies of your string sitting in your address space.
The SecureString class has no members that inspect, compare, or convert the value of a SecureString. The absence of such members helps protect the value of the instance from accidental or malicious exposure. Anyway you can you can use the appropriate members of the Marshal class, such as the SecureStringToBSTR method, to manipulate the value of a SecureString object.



Let me show you an example of how a SecureString should be used:

static void Main(string[] args)

{

    Console.WriteLine("Please enter your password to be encrypted:");

    SecureString password = ReadPassword();

    Console.WriteLine("Decripted password:");

    PrintPassword(password);

    Console.WriteLine("Press any key to quit");

    Console.ReadKey();

}

 

public static SecureString ReadPassword()

{

    SecureString password = new SecureString();                       

    ConsoleKeyInfo key = Console.ReadKey(true);

    while (key.Key != ConsoleKey.Enter)

    {

        password.AppendChar(key.KeyChar);

        key = Console.ReadKey(true);

    }

 

    password.MakeReadOnly(); // make the password read-only.

    return password; // return the encrypted password.

}

 

public static void PrintPassword(SecureString password)

{

    // Uncrypt the password and get a reference to it...

    IntPtr bstr = Marshal.SecureStringToBSTR(password);

 

    try

    {

        // Printing the uncrypted password...

        Console.WriteLine(Marshal.PtrToStringBSTR(bstr));

    }

 

    finally

    {

        Marshal.ZeroFreeBSTR(bstr);

    }

}



kick it on DotNetKicks.com

5 comments:

Anonymous said...

Anybody attacking a .NET product will do it by attaching a debugger, so this is all pretty pointless.

Since the key and the ciphertext is in memory, they can just use your own code to decrypt it.

DevTopics said...

SecureString: Safe from forensics, but not from surveillance

With SecureString, the original unencrypted text never appears in memory, hence it cannot be recovered using forensic analysis.

Unfortunately, SecureString will not protect users from computer surveillance. If someone is watching your PC using spyware, keystroke logger, hidden camera or remote monitor, then sensitive data may be compromised before it ever enters the SecureString object.

http://www.csharp411.com/securestring-safe-from-forensics-but-not-surveillance/

Anonymous said...

This is actually an example of how the SecureString class should not be used. Consider the following statement from your code:

Console.WriteLine(Marshal.PtrToStringBSTR(bstr));

More specifically:

Marshal.PtrToStringBSTR(bstr)

The return value from this function is a regular System.String class, which means the code just circumvented whatever protections it had by using SecureString to start with. It would be better to put the value into a byte array, and write it out one byte at a time, that way you can zero the bytes after you write them, although that is not 100% secure, either.

123 said...

It is very interesting for me to read that article. Thanx for it. I like such themes and everything connected to this matter. I would like to read more soon.
Alex
Cell jammers

Anonymous said...

learn how to protect your valuables
avoid becoming prey for thieves, all they can learn from the book "THINK LIKE A BURGLAR"
if you want to learn more visit site http://secure-your-valuables.com/