Encrypting Web.Config file of a ASP.NET 2.0 application in Webfarm Scenario

Encrypting web.config or app.config

ASP.NET 2.0 came with a rich feature for encrypting web.config app.config file using aspnet_regiis.exe, which supports RSA encryption in webfarm scenario.

Where can I find aspnet_regiis.exe?

Normally this tool is available under the following folder 

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

(If your Operating system installation in other drive use the corresponding one.)

Which section of a web.config can be encrypted?

<appSettings>. This section contains custom application settings.
<connectionStrings>. This section contains connection strings.
<identity>. This section can contain impersonation credentials.
<sessionState>. This section contains the connection string for the out-of-process session state provider.

Why RSA provider ?

When we are using RSA ,which will allow to export the RSA keys. So this can be used in all other server in the farm.

Using RSA Provider

First we have to create a keycontainer, which can be used in all other servers. All the following steps are going to use the tool aspnet-regiis which I mentioned earlier.

1. First we have to create a custom RSA encryption key. For that we need to open the .NET SDK command prompt (Start->Allprograms->Microsoft .Net framework SDK V2.0->SDK Command prompt).Type the following

aspnet_regiis -pc "ShyjuMohanKeys" -exp

The -exp switch indicates that the keys are exportable

2. Next step is we have to specify the provider (if you need know more about provider model follow this link - http://msdn2.microsoft.com/en-us/library/aa479030.aspx) in the web.config file. Add the following section to web.config file.

<configProtectedData>
  <providers>
  <add keyContainerName="
ShyjuMohanKeys
"
           useMachineContainer="true"
           description="RsaCryptoServiceProvider for encryption and decryption"
           name="MyCustomProvider"       type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </providers>
</configProtectedData>

3. Next step is encrypting the sections which we want to secure. For example we can encrypt the connection string section using following command.

aspnet_regiis -pe "connectionStrings" -app "/MywebApplication" -prov "MyCustomProvider"

In the above command you can see the specifying connection string as the section to encrypt and application name "MywebApplication" (Web application deployed in my IIS - localhost).One more thing you have to notice is the provider name, there I am specifying the provider name which is specified in the provider section of the web.config in the webapplication "MywebApplication".

For example encrypting Identity section

aspnet_regiis -pe "identity" -app "/MywebApplication" -prov "MyCustomProvider"

4. After encrypting the connection section it will look like as follows

<connectionStrings configProtectionProvider="MyCustomProvider">
  <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>qZ9OMWTQnsmw6wraCA0EdZyYwZYoQCS3j6UypVHGwKuEDZOCGjoKrE
Qel0lbNk/SvMyLvucIm95vmhoW+zCeh259WaZz5JQcTxXdlpqvbGwt04LD7NqhU79ssc
Zx31R3D9Pbm0XAgOV1T9ep2dRB7E3ZwQLN/TosaDjXxn+TgDU=</CipherValue>
     </CipherData>
    </EncryptedKey>
   </KeyInfo>
   <CipherData>
    <CipherValue>fy8vJEiMkLisFRwmql4B9K9lFvITSDfIcgcy36ro5js=</CipherValue>
   </CipherData>
  </EncryptedData>
 </connectionStrings>

5. Next step we have to export the private and public key into a xml file, so that we can import the key container to other server's in the web farm.

aspnet_regiis -px "ShyjuMohanKeys" "C:\ExportedCustomKeys.xml" -pri

6. Next important step is we have to give the permission for accessing the key.

Normally in a production environment web application will run in a particular application pool and this application pool's identity will be a less privileged account (service account).

 Follow this link for learning more about configuring application pool identity

(http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/
f05a7c2b-36b0-4b6e-ac7c-662700081f25.mspx?mfr=true
)

Type the following command to grand the permission

aspnet_regiis -pa "ShyjuMohanKeys" "DomaineName\Account name"

Steps to follow in the other servers of the Farm

1. In the destination server first we have to import the key using aspnet-regiis tool. Copy the exported xml file to a folder in the destination server. Here I copied to same folder. Type the following command.

aspnet_regiis -pi "ShyjuMohanKeys" "C:\ExportedCustomKeys.xml"

2. Next step is deploying the web application to the server with encrypted web.config file.

3. Granting access permission to the application pool identity user.(the application pool under which application runs)

aspnet_regiis -pa "ShyjuMohanKeys" "DomaineName\Account name"

One of the important thing is deletion of  all ExportedCustomKeys.xml files from the servers. This files are only for moving container file from one server to another.

How to encrypt app.config file of windows\console application?

I saw many people are struggling to encrypt the app.config file of the windows or console applications. The main reason is in availability of tools like aspnet_regiis for app.config  files. We can overcome this by doing some work around.

1. Add a web.config file to this application(windows\console)

2. Add the sections into the web.config file (copy the sections like connection string , keys, identity )

3. Use the aspnet_regiis tool to encrypt the newly added web.config file. Type the following command.

aspnet_regiis -pef "connectionStrings" -app "E:\shyju\Publish" -prov "MyCustomProvider"

After successful execution of the command, the specified section in the web.config will get encrypted.

4. Next step is copy the entire section from this web.config to you app.config file. For example copy the entire connection string section from newly added web.config to app.config file.

Do we need to write any code for reading this encrypted files?

Answer is no, thats the beauty of .Net framework 2.0. It will take care all the decryption for you. Sounds Great! right. Only thing you have to do is use the configuration manager class (Newly added in .net 2.0) for reading the configuration file. It can be web.config or app.config file.

ConfigurationManager.ConnectionStrings
                            ["MySqlConection"].ConnectionString);

These all are newly added features in .Net 2.0. Now we have to write less code to keep the secret information's.