Friday, August 29, 2008

Encrypting sections of the Web.config file - the Continuous Integration way

The following algorithm is not the easiest way to protect your web.config (unlike this solution). There are few advantages, though. First, we can replicate an RSA key container between multiple servers in a Web farm, thus providing a scalable solution. Second - we can automate encryption and container distribution with Continuous Integration. Developers can enjoy a readable web.config file while CI script will take care of encrypted production version.

1. Add the following section to the root of the <configuration> node:

<configProtectedData defaultProvider="MyRsaProvider">
<providers>
<clear />
<add name="MyRsaProvider"
type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
keyContainerName="MySiteKeys" useMachineContainer="true" />
</providers>
</configProtectedData>
Intellisense or Resharper may complain about keyContainerName and useMachineContainer attributes - don't believe it, they just comfused.

2. Now we can create the RSA container and make it exportable:

aspnet_regiis -pc "MySiteKeys"-exp
3. Next step is to encrypt a selected web.config sections:
aspnet_regiis -pef "connectionStrings" "c:\MySite\WebUI" -prov "MyRsaProvider"

The same way you can encrypt connectionString, system.web/membership, AppSettings and any custom configuration section.

Make sure that string attribute values in the encrypted sections (including the configProtectedData) are not split on several lines. The aspnet_regiis tool will try to reproduce the carriage return symbols and encode them:

image

It is not affecting the application execution in any way, but looks weird and confusing.

4. Save the above key to xml file in order to export it from your local PC to the WebServer (UAT or Production)
aspnet_regiis -px "MySiteKeys" "c:\mykeyfile.xml" -pri

-pri option enforces both private and public keys to be exported thus enabling encryption and decryption.

5. Now you have encrypted web.config file and key xml files. The first part - the deployable package creation, is done and your application is ready to be deployed to the web servers.

For the next two steps - deployment and permissions settings, the Continuous Integration script should be executed under account with admin privileges.

Import the key container on WebServer servers:

aspnet_regiis -pi "MySiteKeys" "c:\mykeyfile.xml"
To make Continuous Integration script more defensive, you can clean the container first. The task will attempt to remove key container, failing if container wasn't found, so it should be made fail-tolerant (failonerror="false" for NAnt script).
aspnet_regiis -pz "MySiteKeys"
Be careful to not run this task locally on the container source machine :).

6. Grant an access to the key container to the ASP.NET account

aspnet_regiis -pa "MySiteKeys" "DOMAIN\USER"

If, like me, you are never sure, what identity the ASPNET process runs under - test it by adding this code to any of your ASP.NET pages:

Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name)

No comments:


© 2008-2013 Michael Goldobin. All rights reserved