Protect your passwords - The SecureString Class

The SecureString Class was created to hold sensitive information such as passwords, credit cards, SSNs, etc ... and is located in the System.Security namespace.  It is an extra layer of security to keep prying eyes away on a compromised machine.

What is wrong with using the standard String class for secret information?

  • Strings are not encrypted - so anyone or anything (Malware or Viruses) who have access to your process memory can view the values
  • Strings are immutable - when a String is modified, a new String object is created, leaving two copies on the heap
  • Strings are not pinned - Garbage collection can move the String object around in memory
  • Strings cannot be scheduled for disposal

The SecureString Class solves each of these

  • The SecureString class is encrypted using DPAPI, a data protection api.  The problem with DPAPI is that it is platform dependant.  It is only included in Windows 2000 sp3 and later. 
  • Only one instance of the SecureString object lives in memory
  • You can clear the object when finished and the memory is actually zeroed out
  • Provides a locking mechanism so other code cannot modify the object - MakeReadOnly method

Example (Console application):

Remember to import the System.Security namespace.

        static void Main(string[] args)
        {
            SecureString secureString = new SecureString();

            //the following input code is from http://blogs.msdn.com/shawnfa/
archive/2004/05/27/143254.aspx
            // get the first character of the password
            ConsoleKeyInfo nextKey = Console.ReadKey(true);

            while (nextKey.Key != ConsoleKey.Enter)
            {
                if (nextKey.Key == ConsoleKey.Backspace)
                {
                    if (secureString.Length > 0)
                    {
                        secureString.RemoveAt(secureString.Length - 1);

                        // erase the last * as well
                        Console.Write(nextKey.KeyChar);
                        Console.Write(" ");
                        Console.Write(nextKey.KeyChar);
                    }
                }
                else
                {
                    secureString.AppendChar(nextKey.KeyChar);
                    Console.Write("*");
                }

                nextKey = Console.ReadKey(true);
            }

            //set readonly
            secureString.MakeReadOnly();

            //need password again
            //decrypt
            IntPtr ptr = Marshal.SecureStringToBSTR(secureString);

            //retrieve string - unsecure
            Console.WriteLine(Marshal.PtrToStringBSTR(ptr));
     
            //zero out memory
            Marshal.ZeroFreeBSTR(ptr);
         
            //clear SecureString
            secureString.Dispose();
                    
        }

One thing to note is that once the MakeReadOnly method is called, the Clear method cannot be called; at this time you should use the Dispose method.  Once the SecureString is made readonly, it cannot be undone.

Some of you may be saying this isn't secure! Your right. The section where the pointer is written to the console is unsecure because the SecureStringToBSTR method creates a String object, but this is just an example, not how it should be used.

The SecureString is available to secure data that should never be represented strings.  It is only really available in a few areas and only makes sense for apis that take advantage of it.  One api that takes advantage of this is CredUIPromptForCredentials where a SecureString object is returned for the password and can be used to start a process where the ProcessInfo class accepts the SecureString object.

There are some problems with the SecureString Class.  It does not protect you from users with a debugger.  Hawkeye, a nasty hacker tool but a great developer tool, can decrypt the SecureString objects and its Open Source!  It simply isn't supported in many apis.  However, it does protect from a dump file containing the heap from a crash (how many passwords are found).  Note that most Malware and Viruses have this privilege because they run under administrator.

I think that when more apis take advantage of this object, it will be a great tool.  Glav created a SecureTextBox control for use in forms applications.  It really would be useful if ConnectionStrings were handled in this manner.  It really is of no use for logging in on an Asp.Net application.


Posted by: kjsteuer
Posted on: 4/18/2008 at 2:27 PM
Tags: , ,
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Inside the HybridDictionary

When picking a data structure to store key/value pairs and the size is unknown the HybridDictionary object (System.Collections.Specialized) is a great tool for the job.  The data structure will internally use a ListDictionary while the count is <= 10 and will convert to using a Hashtable afterwards.  If the starting item count is greater than 10, the HybridDictionary will start out with the Hashtable to reduce the overhead generated by the conversion.

A ListDictionary uses an single linked list data structure for implementation so the Item, Add, Remove, and Contain operations are all in linear time.

The Hashtable works off the Object.GetHashCode method for storage.  For each entry, a key, value, and a hashcode is stored.  The entry is placed into a bucket based on this hashcode.  Each time a item is added to the Hashtable, an actual load factor is computed  and is compared to the specified load factor.  The default load factor of 1.0 can be changed during the Hashtable creation, but must be between 0.10 and 1.0.  The load factor is directly related to the probability that a bucket will contain more than one entry.  The lower the value, the less chance of a collision but the trade-off is memory consumption.  Then the actual equals the specified load factor, the Hashtable is reallocated to contain the smallest prime number larger than twice the current number of hashtable buckets.  Dan Mabbutt has some interesting benchmarks regarding the load factor. 

Customized hashing can be achieved by overriding the Object.GetHashCode, and Object.GetEquals methods.  Using the IEqualityComparer interface will enforce these methods.

The operations for the Hashtable are all in constant time on average with the exceptions of reallocation, hash collisions, and multiple items in a bucket.  The Hashtable will automatically rehash collisions.

For a hash table review visit Wikipedia.

Remember that all key objects must be immutable!


Posted by: kjsteuer
Posted on: 3/31/2008 at 12:12 PM
Tags: ,
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (3) | Post RSSRSS comment feed

applicationSettings vs. appSettings

applicationSettings was introduced into the .Net 2.0 Framework.  This is not the same as appSettings which most developers used 1.1, but what is the difference?

Application settings give us more control and most important, intelliscence.  To create an application setting simply view your projects properties and select Settings.

applicationSettings

Here you can see that there are more parameters than the standard appSettings.  Additionally there are the fields Type, and Scope.  This Type is used for intelliscence in Visual Studio.

Within the config file, the following section is added:

    <userSettings>
        <applicationSettings_vs_appSettings.My.MySettings>
            <setting name="MySetting" serializeAs="String">
                <value>MySettingString</value>
            </setting>
        </applicationSettings_vs_appSettings.My.MySettings>
    </userSettings> 

This allows us to use intelliscence in our application now.

        Console.WriteLine(My.Settings.MySetting)

This can be very useful and it is strongly typed so it is faster.  However, applicationSettings are only in console applications, forms applications and web applications, they do not exist in websites.  For the websites you must resort to the old appSettings standard.

To set the setting to a new value simply, set the property and save the settings.

        Console.WriteLine(My.Settings.MySetting) 'MySettingString
        My.Settings.MySetting = "new setting"
        My.Settings.Save()
        Console.WriteLine(My.Settings.MySetting) 'new setting

applicationSettings2

I am not sure why this doesn't exist in the websites.  I came across this when I was getting the error: Configuration system failed to initialize from trying to use the Configuration manager versus using My.Settings.


Posted by: kjsteuer
Posted on: 3/27/2008 at 4:45 PM
Tags: ,
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (3) | Post RSSRSS comment feed