Wednesday, August 22, 2007

SecureString in c#

System.Security.SecureString



Per MSDN:

Represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed. This class cannot be inherited.



Storing any sensitive data like passwords etc in the standard System.String can be a potential threat to the data for the following reasons:


>> It is stored on the Managed Heap and is not pinned in the memory, so the garbage collector can move it around at will leaving several copies in memory. The code will not know that this has happened, and even if it could figure out that the string was moved, there is no way to clear out the other copies. Instead we have to wait for the CLR to allocate another object where the sensitive data is so that the memory gets erased.

>> It's not encrypted, so anyone who can read process's memory will be able to see the value of the string easily. Also, if the process gets swapped out to disk, the unencrypted contents of the string will be written to the swap file.

>> It's not mutable, so whenever it is modified, there will be the old version and the new version both in memory

>> Since it's not mutable, there's no effective way to clear it out when you're done using it

Hence, .NET 2.0 introduced a new class under System.Security namespace called SecureString, that can be used in place of standard Strings to store sensitive values.

Using SecureString eliminates the above mentioned issues as:

>> The SecureString is not stored in the managed heap while standard strings are and therefore it will not be replicated to multiple locations in memory.

>> SecureStrings are stored in an encrypted form. They need to be decrypted when they are used. this period of decryption can be kept as small as possible. So even if the process is swapped out to disk while the string is encrypted, the plaintext will not end up in the swap file.

>> The keys used to encrypt the string are tied to the user, logon session, and process. This means that any minidumps taken of the process will contain secure strings which are not decryptable.

>> SecureStrings are securely zeroed out when they're disposed of. System.Strings are immutable and cannot be cleared when you've finished with the sensitive data

create a SecureString, you append one character at a time:

System.Security.SecureString secString = new System.Security.SecureString();
secString.AppendChar(p);
secString.AppendChar('a');
secString.AppendChar('s');
secString.AppendChar('s');
secString.AppendChar('w');
secString.AppendChar('d');

When the string contains the data you want, you can make it immutable and uncopyable by calling the MakeReadOnly method:

secString.MakeReadOnly();

To read the secure value, use the SecureStringToBSTR() method as follows:

IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(secString);
string sDecrypString = System.Runtime.InteropServices.Marshal.PtrToStringUni(ptr);

The garbage collector will remove SecureStrings when they're no longer referenced, but you
can dispose of a SecureString by using the Dispose() method:

secString.Dispose();

10 comments:

  1. Anonymous04:08

    Thank you, it is a very useful way to secure data..

    ReplyDelete
  2. Thanks. Nice to know that it was of help to you.

    ReplyDelete
  3. Anonymous03:07

    Hi, I'm new in C# and .Net programming and came across this blog and wanted to say thank you. In addition, I'm curious about what happens to the string, sDecrypString? It contains a plaintext decrypted copy of the secured string. Doesn't that defeats the purpose of securing the string? Thanks in advanced for your help.

    Rob

    ReplyDelete
  4. Hi Rob,

    Nice to know that it was of any use to you. Further, yes you are right in saying that sDecrypString does contain a plain text string. But then you do need that in your program in that form. Right? otherwise why would you be storing it in the securestring.

    Although the SecureString class does not prevent fully trusted code which is running in your application from decrypting the contents of the string and doing whatever it wants to do with it, it does provide some other features for atleast making the risk as low as possible . It's all about risk management -- keeping the sensitive data as inaccessible as possible when it's not being used, and being able to erase your records of it when it is no longer needed. And thats precisely what SecureString does.....

    Hope you got your clarification.......


    Thanks
    Ashutosh

    ReplyDelete
  5. Anonymous19:40

    Nice to find a straight forward explanation. It is certainly minor, but I believe you missed the 's around the p.

    Mark

    ReplyDelete
  6. Thanks Mark...

    Indeed I missed the quotes...

    Thanks for pointing out..

    ReplyDelete
  7. Thanks Mark...

    Indeed I missed the quotes...

    Thanks for pointing out..

    ReplyDelete
  8. Thanks Mark...

    Indeed I missed the quotes...

    Thanks for pointing out..

    ReplyDelete
  9. Thanks Mark...

    Indeed I missed the quotes...

    Thanks for pointing out..

    ReplyDelete
  10. This message, is matchless))), it is interesting to me :)

    ReplyDelete