BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Security
.NET 2.0

Creating Secure Strings

Highly confidential information, such as passwords or banking details, should be encrypted in memory during use to reduce the risk that it may be revealed to malware or forensic examination. The SecureString class provides this encryption automatically.

Reading a SecureString

As explained earlier, there is no method or property that allows a SecureString to be easily read. A safe way to access the information is to convert the SecureString to a basic string, or BSTR. This is an unmanaged, null-terminated string that can be accessed using a pointer. To perform the conversion requires the use of the Marshal class in the System.Runtime.InteropServices namespace. To keep the code simple, add the following using directive.

using System.Runtime.InteropServices;

To convert the SecureString to a BSTR and obtain a pointer you can use the SecureStringToBSTR method. To do so, add the following code to the end of the Main method.

IntPtr bstrPointer = Marshal.SecureStringToBSTR(ss);

It is possible to convert a BSTR to a standard .NET string. As you have seen, this would pose a security risk. Instead, it is a good idea to read the BSTR one character at a time. The following code achieves this by looping through the BSTR's characters until the zero value that terminates the string is found. As the BSTR holds Unicode information, the characters are read two bytes at a time. The two bytes are combined to generate a single character, which is outputted to the console for demonstration purposes.

for (int i = 0; ; i+=2)
{
    byte lo = Marshal.ReadByte(bstrPointer, i);
    byte hi = Marshal.ReadByte(bstrPointer, i + 1);
    long l = lo + hi * 256;
    if (lo != 0)
        Console.Write((char)l);
    else
        break;
}

/* OUTPUT

BlackWasp

*/

Removing the BSTR from Memory

Once the processing of the unmanaged BSTR is complete, it should be zeroed and its memory freed. You can perform both actions using the ZeroFreeBSTR method of the Marshal class by adding the code shown below. In real-world solutions, this code should be contained within the finally section of a try-catch-finally block. If not, an unexpected exception could cause the call to be missed, leaving a plain-text copy of the sensitive information in memory.

Marshal.ZeroFreeBSTR(bstrPointer);

Disposing the SecureString

Whenever you are working with SecureStrings, you should dispose of them correctly. The class implements the IDisposable interface so to clear the SecureString from memory, add the following line of code to the Main method. You can now execute the code, knowing that the confidential string is only held in an unencrypted format for the duration of the for loop.

ss.Dispose();
15 June 2010