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

Posted by: Suprotim Agarwal , on 8/6/2008, in Category ASP.NET
Views: 164931
Abstract: 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.
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="var1" value="SomeValue"/>
      </appSettings>
      <connectionStrings>
 <add name="MyConnString" connectionString="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 Object, ByVal 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 Object, ByVal 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.
If you liked the article,  Subscribe to my RSS Feed.   
 
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and a new one recently at The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for nine times in a row now. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that represents premium web sites and digital publications comprising of Professional web, windows, mobile and cloud developers, technical managers, and architects.

Get in touch with him on Twitter @suprotimagarwal, LinkedIn or befriend him on Facebook



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by joe on Saturday, August 30, 2008 11:06 AM
Nice article just what i was looking for thanks again
Comment posted by Erum on Tuesday, September 16, 2008 12:22 AM
very informative......thumbs up..!
Comment posted by Diwakar on Saturday, September 20, 2008 4:16 AM
Nice article. Thanks
Comment posted by Qifar on Saturday, September 20, 2008 9:10 PM
hi,
it's nice and very informative....... thanks
Comment posted by Salil on Sunday, September 21, 2008 12:26 PM
I am unable to change connection string or encrypt web.config file from a custom Windows Forms application used in a installer using the WebConfigurationManager or ConfigurationManager API's. I had to finally resort to the Sytem.Xml API. In the past I have used it in a web application as shown above & it works just great.

Any suggestions would be appreciated.

Thanks,

Salil
Comment posted by Samboy LIms on Sunday, September 21, 2008 7:33 PM
What is the practical usage of this?  Can the non-admin do this?
Comment posted by Suprotim Agarwal on Sunday, September 21, 2008 10:10 PM
Salil: You can use ConfigurationSection class to do so. Check out this article:
http://www.codeproject.com/KB/dotnet/EncryptingTheAppConfig.aspx

Samboy: There are many usages. For eg: If you are using hosting, you may not want someone having access to the webserver, read your passwords or SMTP settings or any other confidential info from the web.config file!

ASP.NET denies all HTTP requests to .config files. So a user can never access your config files, however as I said earlier, any person having physical access to the webserver can.
Comment posted by Prasath on Monday, September 22, 2008 8:54 AM
Hi, Nice article, just the  one I was searching for. thanks :)    





Comment posted by Chris on Monday, September 22, 2008 12:26 PM
This is quality.
Comment posted by Aleho on Tuesday, September 23, 2008 4:56 AM
Hi, Thanks for the info.

I'm using this already for a while because my hosting does not allow the use of executables (shared hosting).
It works fine but to write the config you need a trust level of "Full" and I would rather have it om Medium.
Is there a way to bypass this or create a custom trust level with the right setting(s) to allow the write action?
Comment posted by Suprotim Agarwal on Tuesday, September 23, 2008 11:10 PM
Aleho: Good question. To access the config section in medium trust, you would need to add a requirePermission="false" to <section>.

Here are 3 good links I would like to share:

http://www.leastprivilege.com/
ConfigurationPermissionAndRequirePermission.aspx
http://learn.iis.net/page.aspx/127/
deep-dive-into-iis-7-configuration/
http://msdn.microsoft.com/en-us/library/ms998341.aspx
Comment posted by Sreekant on Wednesday, September 24, 2008 6:30 AM
Its really Good
Comment posted by mahesh on Wednesday, September 24, 2008 7:36 PM
its a good informative article which i am looking for.
Comment posted by Varun Mishra on Thursday, September 25, 2008 5:57 AM
Nice article, Really it good informatics. Thnx.
Comment posted by Michael Washington on Thursday, September 25, 2008 11:09 AM
This is great code. I have been able to use parts of this for a bunch of different projects.
Comment posted by Rupen Anjaria on Saturday, September 27, 2008 6:24 AM
Nice article, just wanted to mention that we have to include "using System.Web.Configuration;" explicit.
Comment posted by Suprotim Agarwal on Monday, September 29, 2008 3:07 AM
Thanks Rupen.
Comment posted by Shreekumar on Thursday, November 20, 2008 10:33 AM
Very Nice, Really it dam goood..
tell me how  to do same with

<system.net>
    <mailSettings>
      <smtp from="mymailid@domain.com">
        <network host="smtp.mail.domain.com" password="mypassword"
          userName="myuserid" />
      </smtp>
    </mailSettings>
  </system.net>
Comment posted by Shreekumar on Thursday, November 20, 2008 11:15 AM
Very Nice, Really it dam goood..
tell me how  to do same with

<system.net>
    <mailSettings>
      <smtp from="mymailid@domain.com">
        <network host="smtp.mail.domain.com" password="mypassword"
          userName="myuserid" />
      </smtp>
    </mailSettings>
  </system.net>
Comment posted by Suprotim Agarwal on Sunday, November 23, 2008 10:19 PM
ShreeKumar: Take a look at the note i had added in the article

'section groups' like <system.net>, <mailSettings> etc. cannot be encrypted. Only 'sections' can be encrypted.
Comment posted by arny on Friday, August 21, 2009 4:22 AM
when I debug it, the first line of code is not working properly,

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

after this part it goes directly to exception part.

any idea?
Comment posted by Suprotim AGarwal on Thursday, August 27, 2009 4:27 AM
Arny: Did you debug and find out the exception thrown. Are you missing a namespace?
Comment posted by yo on Thursday, December 10, 2009 9:30 AM
what does the exception say, you amateur?
Comment posted by 4hmeT on Tuesday, December 22, 2009 11:21 AM
Thank u so much for ur nice article ..
Comment posted by Tom on Wednesday, March 10, 2010 2:24 PM
This was very helpful. I noticed that after I encrypted my appSettings section, I was no longer able to manage those via IIS. It give an error message that says, "Failed to decrypt using provider RsaProtectedConfigurationProvider. The RSA key container could not be opened". Any idea how I can get around that issue?
Comment posted by Haansi on Tuesday, May 4, 2010 3:46 AM
I am not commenting this article but saying doing encription is rubbish. When one can decript programmatically what encription will secure ?
Comment posted by Suprotim Agarwal on Tuesday, May 4, 2010 10:56 PM
Haansi: The encryption comes useful when you are hosting your site and do not want prawling eyes to see your connecting string. The decryption is done by 'our' app, so it is secure.
Comment posted by Funka on Tuesday, June 15, 2010 10:50 PM
I too wonder about how "effective" this really is. Anyone with "prawling eyes" able to look at my web.config in the first place (i.e., an Admin at the hosting company or an attacker who has taken root or sniffed an FTP password) should just as easily be able to create a simple ASPX page in my site that will do exactly what you've shown here. They could create this simple page, run it to decrypt the config, get my private stuff, then re-encrypt it and clean up after themselves so that nobody gets suspicious. I'm actually trying to think of a case where such encryption might help, and where it does seem helpful is if someone were to download the web.config and try to decrypt it on a different machine. (But as I said, if they can get the web.config in the first place, they can probably also write/place files in the same directory!) The article is very nice, please don't get me wrong, but I'm struggling to see how "useful" this really is.
Comment posted by Suprotim Agarwal on Wednesday, June 16, 2010 5:12 AM
Funka: I acknowledge your points, however it is not just prawling eyes. The encryption also makes an app less vulnerable to attackers or malicious users, especially in a shared hosting environment. As you rightly said, it is not fool-proof but adds an extra level of security.
Comment posted by sammy on Tuesday, June 22, 2010 9:54 PM
ConfigurationErrorsException
Am I the only one getting an error when trying to encrypt it.
I can't even see what the error is about, the Intellisense-message is empty!
Comment posted by Tuff on Thursday, June 24, 2010 6:54 PM
I get an error stating access to path 'c:\<<folder>>\mrtidayx.tmp' denied. It appears to only happen when I call the .Save() method.  I've checked to make sure that the folder has Web Sharing enabled, but still no luck.  Any thoughts?
Comment posted by Tuff on Thursday, June 24, 2010 7:15 PM
Nevermind.  I figured it out.  Turns out that since my site was running with network service as the AppPool identity and therefore didn't have rights to modify the file.  Once I changed it to a domain account, everything worked fine.
Comment posted by Tracer on Monday, June 28, 2010 10:21 AM
I have tried again and again to do this on a shared server with medium trust.
IS there any way to get this to work.
It seems I can't even use

Dim config As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)

as it throws an exception.
Comment posted by Kosha on Tuesday, July 20, 2010 5:03 PM
Hi Everyone
Am I the only one that is having problem with this?
I have a asp.net web application and I'm trying to encrypt the ConnectionStrings section. I'm using Visual Studio 2010, however the web application is a 3.5 version
I do NOT have IIS installed. Since I'm running Windows 7, pro

My problem is that nothing happens when I run the code. The connectionstrings settings is never encrypted.
Comment posted by Mohammad on Thursday, July 22, 2010 6:54 AM
It seems like this cannot be used on a commercial webhotel, due to restriction right.
When used on a commercial webhotel I get following error.
Error System.UnauthorizedAccessException: Attempted to perform an unauthorized operation. at .....
Comment posted by Mohammad on Thursday, July 22, 2010 1:57 PM
It seems like this cannot be used on a commercial webhotel, due to restriction right.
When used on a commercial webhotel I get following error.
Error System.UnauthorizedAccessException: Attempted to perform an unauthorized operation. at .....
Comment posted by Ravinder on Tuesday, August 31, 2010 6:34 AM
getting error "WebConfigurationManager not found.." What imports should I include? I tried Imports Sysstem and imports system.web but same problem
Comment posted by Angelika on Thursday, November 4, 2010 2:22 PM
Hi, everybody,
Could anyone  tell me which code need to declare ‘WebConfigurationManager’?
I am using Microsoft Visual Web Developer 2008 Express Edition but in Microsoft Visual Web Developer 2008 Express Edition is not possible to open Visual Studio command Prompt window … so I am trying programmatically encript my web confing file via code below but when I attaching this code here errror where said ‘WebConfigurationManager’ is not declared …
Gratefull for help
Angelika.
Comment posted by Suprotim Agarwal on Friday, November 5, 2010 4:44 AM
Angelika: You need to include the System.Web.Configuration namespace.

P.S: Do not include your email address in the comments as your mail box could get spammed!
Comment posted by Ramgopal Varma on Tuesday, April 19, 2011 1:39 AM
Thank you..Good article.
Comment posted by Davis on Monday, November 14, 2011 9:42 AM
Thanks for sharing this article.
When I run the code, I get:
System.InvalidOperationException: Failed to map the path '/'.

I am running the .Net framework 4.0
I deployed the app to an IIS server and still get the error. Any suggestion?

Thanks
Comment posted by keepCoding on Monday, March 18, 2013 7:17 PM
Thanks much for this useful post.

1. Is there a way to ads / use a Key or Password during Encrypt?

2. If Encrypted without a Key or Password, can others / hackers just use Decrypt() to get to the clear text Web.Config then?

3. For Web Farm case, we need to be able to use the same encrypted Web.Config deployed to multiple IIS Servers via the Export / Import of the RSA Key Container. Can we do these by code as well, please?

This link below has the details about the Web Farm case:
    http://msdn.microsoft.com/en-us/library/yxw286t2.aspx

This would be very useful. Thanks.

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook