Practical ASP.NET

Encrypting the Web.Config File

If you're concerned about keeping critical information in your Web.config file, then you should encrypt it -- or at least the parts that you're concerned about.

I love keeping information in my Web.config file's appSettings section; it lets me change the behavior of a Web site just by changing values in a text file. I especially like keeping connection strings in the connectionStrings element (it lets me ensure that I keep the number of connection strings to a minimum, which enhances connection pooling performance).

My clients don't always agree with me about storing data in the config file. To be more specific, my clients are concerned about keeping sensitive information (like connectionStrings) in a text file. I tell my clients that if people can pull text files off their Web server, then they have problems that even I can't solve.


My clients don't find that a compelling argument.

And, to be honest, they have a point. A sizeable percentage of security breaches are made by people inside an organization -- people the Web site may not protect itself from. So I suggest to my clients encrypt their web.config file. I skimmed over this topic in an earlier column on managing the Web.config file during deployment ("Managing Web.Config Settings During Deployment"). After a couple of reader questions, I'm finally getting around to discussing the topic in detail.

Encrypting Sections
This is the code that I use to encrypt a specific section of the Web.config file. I first select a section using the Configuration object's Sections collection. In this case, I'm selecting the connectionStrings section:

Dim configFile As System.Configuration.Configuration 
Dim configSection As ConfigurationSection 

configFile = System.Web.Configuration.WebConfigurationManager. _
                                   OpenWebConfiguration(Request.ApplicationPath)
configSection = configFile.Sections("connectionStrings")

This code assumes that it's running from a page on the site so I can use the ApplicationPath property on the Request object to get the physical path to the web.config's folder. If you wanted to create a utility, you'd need to hard code the path you pass to the OpenWebConfiguration method.

Now that I have the section, I encrypt it, specifying the encryption scheme that I want to use. The last step is to save the encrypted version back to the config file:

configSection.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider")
configFile.Save()

The result looks like this in the Web.config file:

<connectionStrings 
     configProtectionProvider="DataProtectionConfigurationProvider">
      <EncryptedData>
         <CipherData>
            <CipherValue>...encrypted data... </CipherValue>
         </CipherData>
      </EncryptedData>
</connectionStrings>

The good news is that when you use the ConfigurationManager's ConnectionString collection to retrieve an encrypted connection string, the connection string is automatically decrypted for you. This code works whether the connectionStrings section is encrypted or not:

Dim cnStr As String
cnStr = System.Web.Configuration.WebConfigurationManager. _
          ConnectionStrings("Northwind").ConnectionString 

Since the strings are encrypted using the private key for the Web server, even if the file is stolen from the site, it can't be decrypted on any machine except the Web server. This also means that you can't encrypt the connection string until the application has been moved to the production server: If you encrypt the connection string on the test server and then move your site to the production server, ASP.NET won't be able to decrypt the string using the production server's private key.

On occasion, you'll need to decrypt the web.config section just to check what's actually in the file. This code takes care of that job:

Dim configFile As System.Configuration.Configuration 
Dim configSection As ConfigurationSection 
 
configFile = System.Web.Configuration.WebConfigurationManager. _
                                   OpenWebConfiguration(Request.ApplicationPath)
configSection = configFile.Sections("connectionStrings")
configSection.SectionInformation.UnProtectSection()
configFile.Save()

Command Line Encryption
If you'd prefer not to use code, you encrypt (or decrypt) sections of your web.config file using the aspnet_regiis utility. You must pass the utility the -pe parameter to specify the section to encrypt along with the path name to the config file's folder, and you must also pass the -prov parameter to specify the encryption scheme:

aspnet_regiis.exe -pef section physical_directory -prov provider

This example encrypts the configurationStrings section for a config file in the c:\NorthwindCRM folder:

aspnet_regiis.exe -pef configurationStrings c:\NorthwindCRM 
      -prov "RsaProtectedConfigurationProvider" 

You can also use aspnet_regiis utility to decrypt the section using the -pdf parameter instead of -pef.

Or you could just make sure that no one can steal text files from your Web server.


About the Author

Peter Vogel is a principal in PH&V Information Services, specializing in ASP.NET development with expertise in SOA, XML, database, and user interface design. His most recent book ("rtfm*") is on writing effective user manuals, and his blog on technical writing can be found at rtfmphvis.blogspot.com.

Reader Comments:

Tue, May 4, 2010 Haansi Pakistan

Hi, Encrypting in dotnet is rubbish. Tell me what it will protect when its programmatic decription is possible ? What and how long it will be hidden and to whome ? thanks

Thu, Dec 3, 2009 Sumit Thapar Chandigarh

hi. i tried using this example but am getting an error. "An error occurred executing the configuration section handler for connectionStrings". please help

Fri, Sep 25, 2009 Vivek India

Thanks :)

Tue, Sep 15, 2009 Puneet Singhal

Nice Article, Thanks.

Thu, Aug 6, 2009 Emmanuel Mathew

Thanks it was a nice article. I thought it would be prettu tough to encrypt the config file. But glad to see this so simplified.

Mon, Jul 20, 2009 Donald Ray

Hari: MD5 is not reversible, so if you were to hash your connection string it would be irretrievable. Encryption algorithms like RSA have an inverse function that will give plain text from cipher text.

Wed, Jul 1, 2009 Hari Chennai

Brilliant article! Thanks for that. I have a question though. Why shouldnt I go for md5 hashing which is provided in the system.cryptography namespace?Why should I go for RsaProtectedConfigurationProvider or a DPAPIProtectedConfigurationProvider? Might sound pretty basic, but that question has been haunting me ever since i read this article.

Wed, Jul 1, 2009 =8)-DX

OMAIR, I think anyone in a server-admin position knows that.. a web-app restart should only really matter for heavy-access server. You make it sound like this method of web-config encryption is not good because of the restart.

Thu, Jun 25, 2009 Peter Vogel Canada

The comment about changing the web.config file causing your application to (effectively) restart is an excellent point--and one I should have mentioned. You really do want to encrypt your config file !!AS SOON AS YOU DEPLOY IT!! and not after some users have started working with the application. Thanks for mentioning that!

Thu, Jun 25, 2009 Omair Pakistan

remember all, when you change the configuration file while running, all Sessions would be reset... and data would be lose well.. its nice article... take care. OMAIR

Wed, Jun 24, 2009 Hitesh New jersey,US

Nice article!!!

Wed, Jun 24, 2009 Sujit Mandal Kolkata

Nice article!Thanks.

Tue, Jun 23, 2009 Peter Vogel Canada

Kumar: The access denial error sounds like a permissions problem: for some reason your code is not allowed to update its own config file. Send me an e-mail so that we can dig for some details and see if we can resolve the problem.

Tue, Jun 23, 2009 kumar india

nice article related to encrypting web.config. nice again http://www.planetsourcecode.in

Mon, Jun 22, 2009 never listen 2 heart

I'm getting access denial error at the save method. Do I need to change anything in the config file.

Sun, Jun 21, 2009 Sreenath Iowa, USA

Thanks for the article. We started using moving all the configuration sections from txt files to web.config and encrypt using aspnet_regiis -pef command. Never knew about the code until I saw this post.

Sun, Jun 21, 2009 N M Reddy India

thank you, nice article.
I believe some times it may impact application performance, like worker process spends more time to read and decrypt data from configuration file. For huge traffic applications it is better to write own technique to store and read configuration settings in secured and faster way.

Sun, Jun 21, 2009 Peter Vogel Canada

Thanks!

Wed, Jun 17, 2009

Finally a sensible, easy explanation of how to do this. It's hard to get a 'just the facts' version of something like this.

Add Your Comments Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above