Encrypting connectionStrings in Web.Config using the NetFrameworkConfigurationKey in an IIS Web Farm scenario

One of the most recommended measure during a web application security audit is to encrypt the connectionStrings section from a Web.Config file. If this operation could be quite easy in a single IIS server environment, it could be really difficult in a Web Farm environment with data replication between every servers. If you encrypt this section using the default key named NetFrameworkConfigurationKey on a given server, everything should be fine. However, if the encrypted Web.Config file is then replicated on servers in the Farm, there could be an issue.

You need to know the NetFrameworkConfigurationKey is built with two parts:

  1. A unique ID identifying this key: d6d986f09a1ee04e24c949879fdb506c
  2. The machine GUID: 11cb3f60-488c-4a71-ad45-def6f31e5d62

This would give as an example: d6d986f09a1ee04e24c949879fdb506c_11cb3f60-488c-4a71-ad45-def6f31e5d62. You'll find this key in the folder C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys. If you check on various IIS servers, you'll see the GUID is each time different. As a consequence, if a Web.Config file is encrypted using the key from server 1, it won't be decrypted by the key from server 2 as the latest isn't matching the first one.

To avoid this issue, here are the steps to follow. The scenario detailed here consist in a Primary server from which all data are replicated using Application Provisioning to one or several Secondary server(s) (which includes the Web.Config file). If you don't use Application Provisioning but you want to copy/paste an encrypted Web.Config from a server to another one, this step by step will work too, however you'll have to replace the replication by a copy/paste (of course).

Remarque: I recommend to test this step by step firstly without following the steps where the keys "NetFrameworkConfigurationKey" are deleted from the Primary & Secondary servers. If the step by step without deletion is working well, you'll be able to follow the full scenario to get a clear configuration at the key level.

 

On the Primary server:

  • Open a CMD using Administrator privileges
    • Note: You have to do a right click > open as Administrator even if the CMD is opening by default with the Administrator account
      If you don't open it explicitly using Administrator, privileges aren't enough to execute the following command-lines.
  • Navigate to the folder "C:\Windows\Microsoft.NET\Framework64\v2.0.50727"
  • Execute the following command-line to suppress the existing "NetFrameworkConfigurationKey" keys:
    • aspnet_regiis.exe -pz "NetFrameworkConfigurationKey"
  • Execute the following command-line to create the key "NetFrameworkConfigurationKey" with the private key set as exportable:
    • aspnet_regiis.exe -pc "NetFrameworkConfigurationKey" -exp
  • Execute the following command-line to export the key in an XML file named key.xml including the private key:
    • aspnet_regiis.exe -px "NetFrameworkConfigurationKey" key.xml -pri
  • If the Application Pool identity isn't the default one (ApplicationPoolIdentity) you need to run the following command-line to grant permissions to the Application pool identity to access this key:
    • aspnet_regiis -pa "NetFrameworkConfigurationKey" "Domain\ApplicationPooIdentityName"

 

On the Secondary server:

  • Open a CMD using Administrator privileges
    • Note: You have to do a right click > open as Administrator even is the CMD is opening by default with the Administrator account
      If you don't open it explicitly using Administrator, privileges aren't enough to execute the following command-lines.
  • Navigate to the folder "C:\Windows\Microsoft.NET\Framework64\v2.0.50727"
  • Execute the following command-line to suppress the existing "NetFrameworkConfigurationKey" keys:
    • aspnet_regiis.exe -pz "NetFrameworkConfigurationKey"
  • Copy the key.xml file from Primary server to Secondary server in the folder "C:\windows\Microsoft.NET\Framework64\v2.0.50727":
  • Execute the following command-line to import the key "NetFrameworkConfigurationKey" :
    • aspnet_regiis.exe -pi "NetFrameworkConfigurationKey" key.xml
  • If the Application Pool identity isn't the default one (ApplicationPoolIdentity) you need to run the following command-line to grant permissions to the Application pool identity to access this key:
    • aspnet_regiis -pa "NetFrameworkConfigurationKey" "Domain\ApplicationPooIdentityName"

       

On the Primary server:

  • Execute the following command-line to encrypt the connectionStrings section in the Web.Config file located in the folder "C:\inetpub\wwwroot" (location to change in function of your needs):
    • aspnet_regiis.exe -pef "connectionStrings" "C:\inetpub\wwwroot"

At this stage, the encrypted Web.Config file will be forwarded to the Secondary server using the Application Provisioning (it's where you need to do it yourself if you don't use the Application Provisioning). As the keys are well set, the Web.Config decryption should work fine. However, let's check it.

On the Secondary server:

  • Copy the encrypted Web.Config to another folder like: C:\test
    • Note: It's better to set the Web.Config file to a folder which isn't using Application Provisioning to avoid getting it replace by the encreypted version during this test.
  • Execute the following command-line to decrypt the connectionStrings section from the Web.Config file located in "C:\test":
    • aspnet_regiis.exe -pdf "connectionStrings" "C:\test"

If it works, everything has been applied correctly J

I hope this article has been useful.
Sylvain Lecerf and the French Microsoft IIS Support Team