You ARE protecting your passwords in your config files AREN’T YOU?

When we are writing software for our clients, we have a fiduciary responsibility to ensure the security of their site.

One way to increase security is to ensure that passwords and other sensitive information are not laying around in our config files unsecured (in plain text). All too many times I have seen something like the following in a config file:

Code Sample:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="UserName" value="PresidentSkroob" />
        <add key="Password" value="12345" />
    </appSettings>
</configuration>

Fixing this problem is as easy as using Microsoft’s Data Protection API. Just encrypt the value by calling ProtectedData.Protect(). And to decrypt the value, call ProtectedData.Unprotect().

Both methods take an entropy value (salt), and a DataProtectionScope value that defines the scope for which the value should be encrypted. The scope may be one of the following: CurrentUser – Only the current user can decrypt the value, or LocalMachine – The value can only be decrypted on the local machine. CurrentUser can be a little complicated since it may require you to impersonate users in certain cases, so I just use LocalMachine. This does mean that you can’t ship the config file with the values pre-encrypted because they will not be decryptable on the machine its installed on (it can only be decrypted by the machine that encrypted it).

The functions return a byte array, so I Base64 encode the values prior to writing them to the config file. To do this, I wrote a few extension methods. Here they are:

Encryption:

/// <summary>
/// Converts a string to a protected value (encrypted using Data Protection API)
/// </summary>
/// <param name="value">The value.</param>
/// <param name="entropy">The entropy.</param>
/// <returns></returns>
public static string ToProtectedValuethis string valuestring entropy )
{
    var entropyBytes = Encoding.UTF8.GetBytesentropy );
    var valueBytes = Encoding.UTF8.GetBytesvalue );
 
    var securedBytes = ProtectedData.ProtectvalueBytes,
                                              entropyBytes,
                                              DataProtectionScope.LocalMachine );
    
    return securedBytes.AsBase64();
}

Decryption:

/// <summary>
/// Converts a string to a protected value (encrypted using Data Protection API)
/// </summary>
/// <param name="protectedString"></param>
/// <param name="entropy">The entropy.</param>
/// <returns></returns>
public static string ToUnprotectedStringthis string protectedStringstring entropy )
{
    var entropyBytes = Encoding.UTF8.GetBytesentropy );
    var encryptedBytes = Convert.FromBase64StringprotectedString );
    
    var decryptedBytes = ProtectedData.UnprotectencryptedBytes,
                                                  entropyBytes,
                                                  DataProtectionScope.LocalMachine );
    
    return Encoding.UTF8.GetStringdecryptedBytes );
}

After encrypting these values appropriately, your config file will look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="UserName" value="ADZgAAwAAAABAAAACLYg+TEHoFh88HcfvNTg0yAAAAAASAAACgAAAAEAAAAMFLpAQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA8BdWygYhjUWaw3teJQo04AQAAAACAAAAAAXFMCeBnOURIBAl2DJoQAAAAN7+sLiIZl+x9vPjC16wcmRQAAADS4d9bdlcLF9CmKrsbgGWPM29zAQ==" />
        <add key="Password" value="AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA8BdWygYhjUWaw3teJQo04AQAAAACAAAAAAADZgAAwAAAABAAAAAhfu4ghotvmXphmGWOHFfbAAAAAASAAACgAAAAEAAAAMBMv0D9/mDwktrFSVNIPcwQAAAAwg2IDL1+MOHwdx2A1cax2RQAAACZLB62COjpupN2+pW4yT8LKR5Udg==" />
    </appSettings>
</configuration>

Now you and your clients can sleep a little better at night knowing their sensitive information is just a bit more secure.

This entry was posted in .NET, C#, Configuration, Security and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*
*