Software Development optimize

Encrypting configuration data in ASP.NET 2.0

ASP.NET 2.0 allows developers to easily encrypt and decrypt data elements to keep them from prying eyes. Tony Patton explains how to protect data stored in a configuration file via encryption and describes new features available in ASP.NET 2.0.

I've covered how to work with configuration files in ASP.NET 2.0 and explained configuration file processing, now I'll show how to protect data stored in a configuration file via encryption and describe new features available in ASP.NET 2.0. I begin with an overview of the encryption options and continue with the actual encryption of data values in a configuration file.

Protected Configuration

ASP.NET 2.0 introduces a Protected Configuration feature that enables you to encrypt sections of your machine.config and web.config files by using either the Data Protection API (DPAPI) or RSA encryption. Developers have been begging for this type of functionality so that sensitive data like connection strings, account credentials, and so forth may be secured.

This functionality allows developers to encrypt one or more sections of a configuration file. The following list outlines some of the sections that are likely candidates for encryption:

  • appSettings: Defines and stores custom application values.
  • connectionStrings: Accesses external data sources via database connection strings.
  • Identity: Contains Web application identities, which may include impersonation credentials.
  • sessionState: Configures session state settings for the current application.

You cannot use the Protected Configuration feature on the following sections of web.config and machine.config files:

  • processMode
  • runtime
  • mscorlib
  • startup
  • system.runtime.remoting
  • configProtectedData
  • satelliteassemblies
  • cryptographySettings
  • cryptoNameMapping
  • cryptoClasses

The .NET Framework provides two ways to encrypt configuration files: the aspnet_regiis.exe command-line utility and encryption within developers' application code. This article focuses on the command-line approach.

ASP.NET IIS Registration Tool

The ASP.NET IIS Registration Tool (aspnet_regiis.exe) is a standard part of the .NET Framework installation. It allows you to update the script maps for an ASP.NET application to point to the ASP.NET ISAPI version that is associated with the tool since there may be multiple ASP.NET versions on a system. You can also use the tool to display the status of all installed versions of ASP.NET, register the ASP.NET version that is coupled with the tool, create client-script directories, and perform other configuration operations.

It includes numerous command-line options, including encryption (pef) and decryption (pdf). You can use the /? option to get help on the utility. The encryption utilizes DPAPI to encrypt the data. As an example, I'll use the web.config file in Listing A.

<?xml version="1.0"?>

<configuration>

<appSettings>

<add key="site" value="TechRepublic.com" />

</appSettings>

<connectionStrings>

<add name="db" connectionString="connection details" />

</connectionStrings>

<system.web>

<compilation debug="true"/>

<authentication mode="Windows"/>

<authorization>

<allow users="tester"/>

</authorization>

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">

<error statusCode="403" redirect="NoAccess.htm"/>

<error statusCode="404" redirect="FileNotFound.htm"/>

</customErrors>

</system.web>

</configuration>

With this file, I can encrypt the contents of the connectionStrings section of the config file with the following line:

aspnet_regiis -pef "connectionStrings" "c:\inetpub\wwwroot\trconfig"

The structure of the previous command is simple, as the following list outlines:

  • aspnet_regiis: the ASP.NET IIS Registration tool
  • -pef: the command-line option for encrypting a configuration section of a config file
  • "connectionStrings": the name of the section to be encrypted (case is observed)
  • "c\inetpub\wwwroot\trconfig": the physical address of the Web site on the local box
You will receive a message of success or failure once it completes. As an example, Listing B contains the web.config file with the connectionStrings section encrypted. (Here's a link to Listing B if you want to copy and paste the code.) <?xml version="1.0"?>

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

<appSettings>

<add key="site" value="TechRepublic.com" />

</appSettings>

<connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">

<EncryptedData Type=http://www.w3.org/2001/04/xmlenc#Element

 xmlns="http://www.w3.org/2001/04/xmlenc#">

<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">

<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<KeyName>Rsa Key</KeyName>

</KeyInfo>

<CipherData>

<CipherValue>hlcvZ+8tPctwMZ5L68zsjWR5uySk5iqbGN6vNa94xrvdAEg2hIo1cexVOITMnVHdBfU7rXWoo3X5KfB3JhrBQQZdFXtAGqR7J3I4GUm6JDu7wWgM5Npb0Vyh+l6FwwEQYj7GfulTO+I3rWLkG7E44Sqzv75VG9QIU7oBH0d+jXo=</CipherValue>

</CipherData>

</EncryptedKey>

</KeyInfo>

<CipherData>

<CipherValue>oEe1fu5aiY0AtsgovXG7TVdxSZw8FU1w18LhdSmL5pptKtOnSYIZ6gVzm9B5/n4t5PWsn7BqGmd535JPe4G+TAqIyiniYQEKLXW3YVHRJX19vlwIIn6y3nyyy8gHE2kHC3LBvkqAtE7sbRlVxGSxpA==</CipherValue>

</CipherData>

</EncryptedData>

</connectionStrings>

<system.web>

<compilation debug="true" defaultLanguage="c#" />

<authentication mode="None" />

<authorization>

<allow users="tester"/>

</authorization>

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">

<error statusCode="403" redirect="NoAccess.htm"/>

<error statusCode="404" redirect="FileNotFound.htm"/>

</customErrors>

</system.web>

</configuration>

The rest of the file remains intact, but you may choose to encrypt other sections as well. For example, you may encrypt the appSettings section from the example file to mask its data from prying eyes.

If you use an encrypted file, it will not cause problems with .NET code because the .NET Runtime takes care of it; there is no additional code to write once you encrypt one or more configuration file sections.

In order to view or edit the file, you will need to remove the encryption, which is easy to do with the command line. The following line undoes the previously applied encryption to the connectionStrings section of the web.config file.

aspnet_regiis -pdf "connectionStrings" "c:\inetpub\wwwroot\trconfig"

This returns the file to the plain text version of the file, so you can make changes and reapply encryption when editing is complete.

Encryption options

By default, the DPAPI is used for encryption with the machine store; however, you may opt to use RSA for encryption with a user store. The DPAPI- and RSA-protected configuration providers used to encrypt sensitive data in configuration files can use either machine stores or user stores for key storage. To use it with the user store, you must add a configProtectedData section to your Web.config file and set the useMachineProtection attribute to false. The concepts are beyond the scope of this article, but there are many online resources where you can learn more about the various options available with the DPAPI and RSA.

Protect your sensitive data

Developers have no more excuses when it comes to exposing sensitive data in an application's configuration file. ASP.NET 2.0 allows you to easily encrypt and decrypt data elements to keep them from prying eyes. If you choose to use the command-line option or roll your own code, make sure to protect that data.

Do you use configuration files to maintain ASP.NET application data like connection strings? If so, did the transparency of the ASP.NET 1.x bother you, and will you use the new security features of ASP.NET 2.0 to secure your data? Share your thoughts and experiences with the .NET community.

Tony Patton began his professional career as an application developer earning Java, VB, Lotus, and XML certifications to bolster his knowledge.

---------------------------------------------------------------------------------------

Get weekly .NET tips in your inbox TechRepublic's free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically subscribe today!

About

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

8 comments
animariammathew
animariammathew

Can we encrypt a key value in a section? For Eg: in the example given in this site, i want to encrpyt the key site in the appsettings.

tecchy
tecchy

Maybe i read into this wrong, but how secure can it be if the key is included in the config file? To me that just adds an annoyance to a would be attacker, not a hinderance.

Justin James
Justin James

Good stuff, thanks! I always thought that ASP.Net put WAY too much sensitive information into those config files, but not using them means you are reinventing the wheel. Encryption combined with a strong user rights policy is the way to go. Thanks! J.Ja

ashfaqec
ashfaqec

This article was a good one. I liked it.

cnuforu9
cnuforu9

This is definitely a good one....

kevinphillips81
kevinphillips81

If I needed to encrypt data previously, I'd have to write my own encryption class and then convert configuration values on fly. This way there's far less to do - once you've finished a project, encrypt your data and roll it on. Definitely a step in the right direction.

HavaCigar
HavaCigar

Especially if you are using DPAPI in a web farm. Machine level is hinderance enough, user level is insane, unless you use the app pool identity. How many app pools are you running... Have you tried to back up a key container or recreate it on another machine? Sure, it's just code, but the keys need to be somewhere for the key container to be re-created. That's a security risk right there. If you have code to read one container and create another, that code is a security risk, even using protected strings. Is it better than nothing? You bet, but it's not an enterprise solution.