Friday, 26 April 2013

Encrypt web.config sections for Azure

Introduction

Encrypting web.config sections that contain passwords is good, firstly as defence in depth (if someone was able to access your config files) but also, actually, is good practice in development teams where everyone does not need to know what the passwords are, it just raises the risk of something happening and not knowing who leaked the information out!

Anyway, this is easy enough in ASP.net using aspnet_regiis.exe which somes with the framework and does various things including encrypting sections in web.config.

Quick Guide


There is a good set of articles starting here: http://blogs.msdn.com/b/sqlazure/archive/2010/09/07/10058942.aspx which describes having to do something slightly different when your site is hosted in Azure (the link is part 1 of 4 but there are no links to the next post so you need to click on September 2010 on the right to find the other parts). It involves downloading a custom encryption provider from http://code.msdn.microsoft.com/pkcs12protectedconfg, creating or buying an X509 (SSL) certificate which you should upload to Azure as you normally would (instructions in parts 1 and 2 of the guide). You then need to build the protectedconfig library and put it into the same directory as the web config that contains the sections you want to encrypt. You should also reference the dll in your project for use at runtime. You then modify the web config to add in the custom provider configuration like this:

<configuration>
  <!-- everything else -->
 <configProtectedData>
    <providers>
      <add name="CustomProvider" thumbprint="ABC123etc..." type="Pkcs12ProtectedConfigurationProvider.Pkcs12ProtectedConfigurationProvider, PKCS12ProtectedConfigurationProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34da007ac91f901d" />
    </providers>
  </configProtectedData>
  <!-- anything else -->
</configuration>

which tells the protected config which certificate to use for encryption/decryption (put the relevant thumbprint in the config section). This will need to be present both on the local machine and on the Azure service that you will be uploading to. Note, you do NOT need to declare this configuration section at the top of the web.config.
You then need to run the following command from a Visual Studio command prompt in the same directory as the web.config. Remember to make sure the pkcs12protectedconfig.dll is in the same directory: aspnet_regiis -pef "connectionStrings" "." -prov "CustomProvider" 
Note that you need to specify the section you need to encrypt in this command, otherwise the other options are the same as above.

Things to Note

If you want to encrypt your own custom section, you have extra work. You need to install the dll that defines the configuration section into the GAC of your development machine, even if it is included in the project because aspnet_regiis will not look in the project to find it. You will then need to change the declaration of the section in web.config to include the GAC fields (culture, version, publickey token). After you have encrypted the section, you can uninstall the library from the GAC, change the config section back to a local reference and then re-build your project afterwards, otherwise the project will start to think the reference that was local is now global and it will break when you upload it. If you want to find the public key token of your dll, run sn -T name.dll from a Visual Studio command prompt.

You cannot encrypt all sections, if you try, you might get an illogical error like "the configuration section 'system.net' was not found". In this specific example, you cannot encrypt the top-level entry but you CAN encrypt further down, for example: aspnet_regiis -pef "system.net/mailSettings/smtp" "." -prov "CustomProvider"
Post a Comment