3/23/13

Encrypting ASP.Net Application Settings

When storing sensitive information in our web.config files, we may want to keep this information secured by encrypting the settings. We can easily do this by using the ASP.NET IIS registration tool (aspnet_regiis.exe) found in the Visual Studio command prompt. This tools allows us to encrypt our settings by just using a couple of command lines, but there are a few things that we should know before we start encrypting our configuration settings.
  • Encryption is done at the section level not setting
  • Uses the current machine key for encryption

Section Level Encryption

This tool allows us to encrypt an entire section not just an entry. If our settings are in the appSettings section, any other settings in this section will also be encrypted. If we need the ability to have clear text settings, we may not want to use this section. The reason for this is because the entire section is changed to an XML structure that is encrypted data. To illustrate this, let’s encrypt the following section:

  <appSettings>
    <add key="Password" value="12345789"/>   
  </appSettings>

By running the following command using the Visual Studio command prompt (under the Visual Studio Tools menu):

aspnet_regiis.exe -pef appSettings "C:\myfolder"

This command basically indicates that we want to encrypt (-pef) a section (appSettings) using a physical path (mypath) . By default, the tool looks for a web.config file within the folder.  There is also support for virtual directories using -pe.

After the command is successful, our settings are encrypted and changed to the following format:

<appSettings configProtectionProvider="RsaProtectedConfigurationProvider">
    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
      xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
 <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
          <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <KeyName>Rsa Key</KeyName>
          </KeyInfo>
          <CipherData>
            <CipherValue>Lyx2UzIumZmg/MRAUPn/Vr1K5grmHlgyqSzvb5qk23SdsGrZWEZ5TinhxUFGVOr12cSTJsAzuGbpiDqUvuP/W/EqS+p4bRybKzNioVhwLK+tb8sm3o0XpIPHEQFVOzKRtPzPznBvzfVK0HPF1FF9+T2gkoDoae2UzDFfX3duKM0=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>srK0/WwBH60H2jjl62waDnt9MZeOfgVqdwsXVsp2MQe0gtIbSd8LZtjZXIdDCom/1T7oVn+Fped7YwqaQA84no2yl211aw3vluRdPeaud0FfDz6pLgimzA==</CipherValue>
      </CipherData>
    </EncryptedData>
  </appSettings>

All the entries under the appSettings are combined in the EncryptedData section. The framework takes care of the decryption when we use the Configuration Settings API, so the code does not have to change. If we need to see what the value is for a particular setting, we need to decrypt the section. To do this, we just need to run this command (Visual Studio command prompt):

aspnet_regiis.exe -pdf appSettings "C:\myfolder"

*Note that we are now using –pdf to decrypt the section
.
Encrypt Application Settings

A better approach to encrypt settings with sensitive information is to add application settings to your project. This adds a custom section that can be independently encrypted. For example, we can add an application setting to our project by using Visual Studio Add New Item – Settings File and add the Password setting.  Visual Studio generates a new setting section in our configuration file like the one below:

<applicationSettings>
    <Encrypt.App>
      <setting name="Password" serializeAs="String">
        <value>123456789</value>
      </setting>
    </Encrypt.App>
  </applicationSettings>

The section that we need to encrypt is under the applicationSettings element. Since we now have an isolated section, we just need to encrypt the Encrypt.App section without messing other settings. We can do this by running this command:

aspnet_regiis.exe -pef applicationSettings/Encrypt.App "C:\myfolder"

When running the command, we use the applicationSettings/Encrypt.App XPath to only encrypt the custom section. This allows us to isolate the encryption to the one section thus enabling us to add other application sections with clear text. The decryption is done by the framework, and it is transparent to the code.

Our section gets encrypted and looks as follows:

<applicationSettings>
    <Encrypt.App configProtectionProvider="RsaProtectedConfigurationProvider">
      <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
        xmlns="http://www.w3.org/2001/04/xmlenc#">
 <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
   <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
              <KeyName>Rsa Key</KeyName>
            </KeyInfo>
            <CipherData>
              <CipherValue>Q818+69UTEO7SSn1+ll7kwZQuklVdR3lZu6nGsPdfnXmOxfqeyaGr+hJ9Ieuao0XFTD/Bv4QjYODxlsdUpre+VjeG3IugvsKzbngB9naRAS7pn9a4OUrQGa1f03Tvo7z103TyMAAyZZNEb+BQTfOqArxxVO6iMM2Fgoc7d//VEQ=</CipherValue>
            </CipherData>
          </EncryptedKey>
        </KeyInfo>
        <CipherData>
          <CipherValue>usKSkMsAfuPZHvyieiru1Nh9xlYDy9HryOmxHQPgCu8s4HJ1y/zfmtV7uM4ywV1+AIrBHt8l4GhL5KK+1HMbWjpcB/VC17vyTt6Mv7eEL7hDO5ASYQ2Zxsxiw6rnASK3jn5WqDQuA+WDUF7ZvE8rJPqJlydISyn97pspIxqQd+Y+rwAOq/+I87oXFmlMEZWk</CipherValue>
        </CipherData>
      </EncryptedData>
    </Encrypt.App>
  </applicationSettings>

We should note that the Encrypt.App section has an attribute (configProtectionProvider) which indicates that only that section is encrypted, and the applicationSettings (element) is not affected.

Machine Key

When we use this approach, we must be aware that the encryption is done using the current machine key. This means that if we encrypt this setting on the development box, we cannot just copy the encrypted setting to another machine because a different key would be used during the decryption process of the settings, and this would fail.

 We will need to be mindful that the encryption needs to be done in each box where this needs to be supported, so before taking this approach we must make sure that this is not a problem with the teams that support all the different environments. 

I hope this article provides you with the tools to help you make sure settings secure.