Web.config Encryption

In my last post, I showed how web.config transforms can be used to manage the complexity of config files in an ASP.NET project. One thing that often comes up in mature environments is that certain parts of the web.config are need to know only. Examples include production database passwords, payment gateway authentication keys, etc. Of course, this isn't restricted to production environments, but is most common there.

Fortunately, there is a solution to this built right into the ASP.NET engine: Encrypted Config Sections. Once the sensitive sections of the web.config transform files have been encrypted, the files can be added to source control and tracked just like any other file in the project without fear that the sensitive data will be mishandled in any way.

In order to encrypt the files, access to the production web server is required. All the following steps must be performed in an elevated (run as administrator) command prompt or they will fail with no useful exception information.

Exporting the Machine Key

Create an exportable, machine-level RSA key:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pc "MyWebServerRSA" -exp

To export the key from one machine to use on another in the same environment/cluster:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -px "MyWebServerRSA" "MyWebServerRSA.xml" -pri
The new key file can be found in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

Importing the Machine Key

For each machine in the web farm do the following:
Copy the exported RSA key to that machine, then import that key.

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pi "MyWebServerRSA" "MyWebServerRSA.xml" -exp

Authorizing the Machine Key

For each machine in the web farm do the following:
Authorize the user to use the key. MyWebServer is the App Pool name.

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pa "MyWebServerRSA" "IIS APPPOOL\MyWebServer"

Configuring Web Application to Use Imported Machine Key

Add the custom encryption provider to the web.config right after the configSections node. This step is necessary whenever you plan to share the encrypted configs across multiple servers.

<configprotecteddata>
<providers>
<add keyContainerName="MyWebServerRSA"
description="Uses RsaCryptoServiceProvider to encrypt and decrypt"
name="MyWebServerRSAProvider"
type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</configProtectedData>

Now encrypt the section containing the sensitive data using the configured provider. This only encrypts the web.config, not any of the transform files. In this example, we only encrypt the connectionStrings configuration node.

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pef connectionStrings C:\MyWebServer -prov MyWebServerProvider

Now the connectionStrings node is encrypted using the key on the production server. Open the web.config file and copy the whole node. Paste it into the config transform for the production environment. Add the xdt:Transform="Replace" attribute to the connectionStrings node. Without this attribute, the node from the base web.config will not be replaced by the encrypted node.

Decrypting the Encrypted Section

Due to password retention policies and staff turnover, changed to the encrypted section may be necessary. The encrypted section can be decrypted by running the following command from an elevated command prompt on the production server:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pdf connectionStrings C:\MyWebServer

Comments

Popular posts from this blog

TFS to SVN Conversion with History

Simpler Tests: What kind of test are you writing?

Architecture at different levels of abstraction