Pages

Friday, November 11, 2011

Programmatically Encrypt and Decrypt Configuration Sections in web.config using ASP.NET 2.0 & ASP.NET 3.5


The ASP.NET Configuration API provides support for encrypting and decrypting configuration sections in web.config. This feature comes extremely handy when you need to hide sensitive information like passwords. In this article, we will explore how to encrypt and decrypt sections of the web.config.
We can encrypt the configuration sections by using two built-in providers: DPAPI (Windows Data Protection API) Provider or the RSA provider. The RSA provider (default) uses an RSA key which holds public and private keys, where as the DPAPI provider uses built-in machine-specific key. Let us explore the steps required to encrypt the sections using RSA.
Step 1: Open Visual Studio > File > WebSite > Select the language (C# or Visual Basic) and location to create a new ASP.NET website.
Step 2: Now add a web.config file to the project. Right click the project > Add New Item > Web Configuration File
Open the web.config and add the following sample entries in the file between the <configuration> tag as shown below:
<configuration>
      <appSettings>
            <add key="var1value="SomeValue"/>
      </appSettings>
      <connectionStrings>
 <add name="MyConnStringconnectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=True;" />
 </connectionStrings>
      <system.web>...
</configuration>
 
Step 3: Now add two buttons to the page, called btnEncrypt and btnDecrypt. We will use these buttons to encrypt and decrypt the sections of the web.config file. Add the following code in the button click event of the two buttons:
C#
string provider = "RSAProtectedConfigurationProvider";
string section = "connectionStrings";
 
protected void btnEncrypt_Click(object sender, EventArgs e)
{
try
{
    Configuration confg = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
    ConfigurationSection confStrSect = confg.GetSection(section);
    if (confStrSect != null)
    {
        confStrSect.SectionInformation.ProtectSection(provider);
        confg.Save();
    }
    // the encrypted section is automatically decrypted!!
    Response.Write("Configuration Section " + "<b>" +
        WebConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString + "</b>" + " is automatically decrypted");
}
catch (Exception ex)
{
   
}       
}
 
protected void btnDecrypt_Click(object sender, EventArgs e)
{
try
{
    Configuration confg = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
    ConfigurationSection confStrSect = confg.GetSection(section);
    if (confStrSect != null && confStrSect.SectionInformation.IsProtected)
    {
        confStrSect.SectionInformation.UnprotectSection();
        confg.Save();
    }
 
}
catch (Exception ex)
{
 
}
}
VB.NET
Private provider As String = "RSAProtectedConfigurationProvider"
Private section As String = "connectionStrings"
 
Protected Sub btnEncrypt_Click(ByVal sender As ObjectByVal e As EventArgs)
Try
      Dim confg As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
      Dim confStrSect As ConfigurationSection = confg.GetSection(section)
      If Not confStrSect Is Nothing Then
            confStrSect.SectionInformation.ProtectSection(provider)
            confg.Save()
      End If
      ' the encrypted section is automatically decrypted!!
      Response.Write("Configuration Section " & "<b>" & WebConfigurationManager.ConnectionStrings("MyConnString").ConnectionString & "</b>" & " is automatically decrypted")
Catch ex As Exception
 
End Try
End Sub
 
Protected Sub btnDecrypt_Click(ByVal sender As ObjectByVal e As EventArgs)
Try
      Dim confg As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
      Dim confStrSect As ConfigurationSection = confg.GetSection(section)
      If Not confStrSect Is Nothing AndAlso confStrSect.SectionInformation.IsProtected Then
            confStrSect.SectionInformation.UnprotectSection()
            confg.Save()
      End If
 
Catch ex As Exception
 
End Try
End Sub
 
In the code above, we open the web.config file as a System.Configuration.Configuration object using the specified virtual path. We then call the GetSection() to retrieve the specified ConfigurationSection object, in our case connectionStrings. The ConfigurationSection.SectionInformation property gets us the SectionInformation object, and then we finally call the ProtectSection() method on the SectionInformation object to mark the section for protection.
Similarly while decrypting the section, we call the UnprotectSection() method of the SectionInformation object.
Step 4: Now run the application and click on the Encrypt button. Now close the application > Open the web.config file. You will observe that the <connectionString> has been encrypted in the following manner:
<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>ZehN7B+VXBdJTe1X3NFz9Uz3NqxvjSMmbytLeHGNlZa4
JkkpRkXzphm5sedHeMTk5KZCHxoYrJ4ssJ0OcZnzLxNUrAB9Ie3y8xJVWJ2s0RQ
dmaGk5bSJADE1xKJBuOtDIOi/Ron7qJDWXwllC3v
vmNwgabmJ9RU+RN35TOQpznc=</CipherValue>
     </CipherData>
    </EncryptedKey>
   </KeyInfo>
   <CipherData>
    <CipherValue>q2amqNwjeyEbMxF5pZ3XqfboNUJKSml773mPkISGi6uWCWCDPs
0ICClmH1eQYcsI9FlxFvEfyRyRRugqOU2xe+gd3aRZEZ5irpGFB45Fn6M+te7kg
OeTK1gjGEsbeaNjBNwgpcXMh9RiA9xVOvWlLAyJ3u8DsDQ+4JmM/zTUtxer/8Dl
UI7+u8D+9V4b5tWxShp4BToMFdTcefhMb19pGdn+jocGet
WBJirO5CJsLXI=</CipherValue>
   </CipherData>
 </EncryptedData>
 </connectionStrings>
Note: If you are running this application from the file system, when you close the application, Visual Studio will display a dialog with the message of "The file has been modified outside the editor. Do you want to reload it?" Click yes and then view the web.config.
Step 5: Run the application again and now click on the Decrypt button. You will observe that the <connectionStrings> section is no longer encrypted and can be read as plain text.
Note: Take a note that 'section groups' like <system.net>, <mailSettings> etc. cannot be encrypted. Only 'sections' can be encrypted, except for a few like <configProtectedData>, <processModel>, <httpRuntime> etc. which has to be accessed by ASP.NET/ISAPI and hence cannot be encrypted using the normal way. To encrypt these sections use aspnet_setreg.exe command-line tool.
You can also encrypt and decrypt sections in the Web.config file using the aspnet_regiis.exe command-line tool.
Encryption:
aspnet_regiis.exe -pef "connectionStrings" "C:\Inetpub\wwwroot\YourWebSite" –prov "RSAProtectedConfigurationProvider"
Decryption:
aspnet_regiis.exe -pdf "connectionStrings" "C:\Inetpub\wwwroot\YourWebSite"
Although ASP.NET is configured to reject all requests for the .config extension, however once you deploy your application to a webserver, there remains chances when sensitive information can be read by those having a file system access to the server. ASP.NET provides us some easy to use options for protecting configuration sections, and we should utilize these options to the fullest. I hope this article was useful and I thank you for viewing it.

No comments:

Post a Comment