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.
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
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
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"
<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.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pdf connectionStrings C:\MyWebServer
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
Post a Comment