Sunday, October 19, 2008

Getting some class in .NET

I would like to start a new trend here, to start exploring some of the thousand's classes that we have in .NET. I'l start with....

The SecureString Class.
This class can be used to store sensitive information in memory while working with it.
The normal string is stored in "clear" text, or not encrypted while you are working with it. Even when the GC has collected it or has moved the string, it still remains accessible from other code.

The SecureString class encrypts the data and keeps it so untill you explicitly decrypt it. Sandly the data is encrypted using Data Protection API (DPAPI), so it only works on NT-based platforms. It would be nice to have a CLR encryption so that it could be more platform independent. To make sure only hou can decrypt the string the keys used to encrypt the string are tied to the user, logon session, and process. Than means that only trusted code running on the same process that started the encryption can decrypt the string.

Here is how to use it.


System.Security.SecureString ss = new System.Security.SecureString()
string pwd = "Password";
foreach(char c in pwd.ToCharArray())
{
ss.AppendChar(c);
}


One thing to take notice of is that you can not just do ss.ToString() and expect to get the password. Doing it like this will only return the type of the object. This is of cource by design, it wouldn't be so secure if it was that easy. The SecureString is, as all other classes derived from the System.Objec class but it doesn't overrides the ToString() method. Instead you have to use the SecureStringToBSTR class to get a copy of the string to a long pointer and then the PtrToStringBSTR to print it, like this.


IntPtr pointer = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(SecureString object);

Console.WriteLine(System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pointer));



Another ting to be aware of is that, because we are playing with unmanaged code the GC won't collect it, so we must free the pointer object by calling the ZeroFreeBSTR method.
System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(pointer);

To sum it up this is how to write and read the SecureString.


System.Security.SecureString ss = new System.Security.SecureString()
string pwd = "Password";
foreach(char c in pwd.ToCharArray())
{
ss.AppendChar(c);
}

IntPtr pointer = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(SecureString object);
try{
Console.WriteLine(System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pointer));
}
catch(){

}
finally{
System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(pointer);
}



/k