Main FAQ Category: Configuration (10)
Also in: Beginner (39) 
How to programmatically Encrypt and Decrypt sections of web.config file?
Posted: 25-Mar-2008
Updated: 25-Mar-2008
Views: 13114

Asp.Net 2.0 has built-in support for encryption and decryption of configuration file sections
with the .Net 2.0 Configuration API.

There are various sections of typical web.config file that usually contain sensitive information:
  • <connectionsStrings> - username and password used to connect to databases
  • <identity> - usernam and password needed for runtime impersonation of fixed identity
  • <system.net/mailSettings/smtp> - your smtp server username and password
  • etc
These important parts of web.config files are ideal candidates for encryption, especially if your website is hosted on
shared-hosting.

By using the built-in Encryption methods we can protect those configuration sections, so even if someone somehow manages
to obtain our web.config files or just take a brief look at them , there will not be much for him to see there.

The fun part is that those encrypted sections are automagically decrypted on-the-fly when our web application reads them,
so no change in application code is needed to be done after we protect web.config!

ASP.NET 2.0 comes with two encryption providers we can use to protect our configuration files:
  • DataProtectionConfigurationProvider
  • RSAProtectedConfigurationProvider
  • also you can implement your own Providers, because its a plugin based model
The DataProtectionConfigurationProvider uses Windows Data Protection API (DPAPI) and this provider
uses a amchine-specific secret key for encryption and decryption.
This means that when you encrypt some data on one server, you can only decrypt it on the same server.

If you need to move configuration files with encrypted sections from server to server or if you have a Server-Farm
you will need to use the
RSAProtectedConfigurationProvider. This provider uses RSA public key protection,
and you can use command line tool aspnet_regiis to create, import and export keypairs for encryption.

more on that on this link: http://msdn2.microsoft.com/en-us/library/ms998283.aspx

We will consider the simpler case where we use a machine specific DataProtectionConfigurationProvider
to programmatically encrypt our configuration files.
We pass the DataProtection provider name as a string to the ProtectSection method to protect our config sections.

here are two simple methods to protect and unprotect your config files sections.

using System.Web.Configuration;


public void EncryptSection(string sectionName, string provider)

{

    Configuration cfg =  WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);


    if (cfg == null)

        return;

    ConfigurationSection section = cfg.GetSection(sectionName);

      if (section == null)

         return;

      if (!section.SectionInformation.IsProtected)

        {

            section.SectionInformation.ProtectSection(provider);

            cfg.Save();

        }           

    }

 

    public void DecryptSection(string sectionName)

    {

        Configuration cfg = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

        if (cfg == null)

            return;

 

        ConfigurationSection section = cfg.GetSection(sectionName);

        if (section == null)

            return;

 

        if (section.SectionInformation.IsProtected)

        {

            section.SectionInformation.UnprotectSection();

            cfg.Save();

        }           

 

    }


and here is an example on how to use these methods to encrypt/decrypt conectionStrings section of your web.config file:

        EncryptSection("connectionStrings","RSAProtectedConfigurationProvider");

and

        DecryptSection("connectionStrings");


or using the DataProtectionConfigurationProvider:


        EncryptSection("connectionStrings","DataProtectionConfigurationProvider");

and

        DecryptSection("connectionStrings");


To be positive that our configuration file is indeed protected, here is a code that
reads the web.config file from website root using server's FileSystem IO and
displays it in the TextBox component on ASP.NET page:
(we must use the IO commands to read the web.config file to see if its encrypted,
because if we would just read the settings directly from our web application they
would be decrypted on the fly and we would receive the real values).
When using FileSystem IO functions to read the web.config file we receive its true
encrypted contents:
 

    using System.IO;


    public void ShowWebConfigFile()

    {

            StreamReader sr = File.OpenText(Path.Combine(Request.PhysicalApplicationPath,"Web.Config"));

            string contents = sr.ReadToEnd();

            sr.Close();

            webconfig.Text = contents;

 

            TextBox1.Text = WebConfigurationManager.ConnectionStrings["local"].ConnectionString;

    }

and here is how our connectionStrings section should look when read this way:

<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
  <EncryptedData>
   <CipherData>
 <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAevxuCHpsWkK7mJZZB5u9DQQAAAACAAAAAAADZgAAqAAAABAAAADTY4+
89xTx8n6fgJu3M4AEAAAAAASAAACgAAAAEAAAAJj77evc30ixlYD7sXdZyUbIAAAATK3ZOyiXebQMhT7KOT1TpRDqPxd/zeD2uwg0
4LeC7CHmMquRKcXGI5Xb7LJnNKysbfXycu7ZmUgd4i7mp3ly/unc/FVWG9PAk6b5LG8BTsdNzTQeZYT7u8Iap2BDFKPgiZqLA4SvM
ti1MyjAK6P+lQCp0irWiE2yqWpMiQ82+k1SZj6AdYjNvYLmoAPFzqX1++ybMdcHueXsv4dvd5Fw2fFTh6iiBdR2xQtvgMrtP9OHmm
CTM1IJ6G8Jv0oxqG7J1b3JWQSIs9MUAAAA4/q1tlT5sNGslF4/yogmvKEz4MY=</CipherValue>
   </CipherData>
  </EncryptedData>
 </connectionStrings>