Return to HomePage



Note: This document is now live on MSDN! See http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000005.asp

How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI


J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley
Microsoft Corporation
May 2005

Applies To

* ASP.NET 2.0
* Windows 2003

Summary

This How To explains how to use the DPAPI Protected Configuration provider and the Aspnet_regiis.exe tool to encrypt sections of your configuration files. You can use this tool to encrypt sensitive data, such as connection strings, held in Web.config and Machine.config. The DPAPI Protected Configuration provider supports machine and user level stores for key storage. The choice of store is largely dependent on whether or not your application shares a server with other applications and whether or not sensitive data must be kept private to each application.

Contents

* Overview
* What's New in 2.0
* Summary of Steps
* Step 1: Identify the configuration sections to be encrypted
* Step 2: Choose the Machine or User Store
* Step 3: Encrypt Your Configuration File Data
* Web Farm Scenarios
* Additional Resources

Overview

Configuration files such as Web.config are often used to hold sensitive information such as user names, passwords, database connection strings and encryption keys. The most common sections that contain sensitive information that you need to encrypt are:

* <appSettings> Custom application settings.
* <connectionStrings> Connection strings.
* <identity> Web application identity. Can contain impersonation credentials.
* <sessionState> Contains connection string for out of process session provider.

Encrypting and decrypting data has a performance overhead. To keep this overhead to a minimum, only encrypt the specific sections of your configuration file that store sensitive data.

What's New in 2.0?

Prior to .NET Framework 2.0, there was limited support for configuration file encryption. The .NET Framework 2.0 introduces a Protected Configuration feature which you can use to encrypt sensitive configuration file data by using a command line tool. The following two Protected Configuration providers are provided although you can also implement custom providers.
* RSAProtectedConfigurationProvider This is the default provider and uses the RSA public key encryption to encrypt and decrypt data.
* DPAPIProtectedConfigurationProvider This provider uses the Windows Data Protection API (DPAPI) to encrypt and decrypt data.

This How To explains how to use the Aspnet_Regiis.exe tool with the DPAPIProtectedConfigurationProvider and DPAPI to encrypt sections of your configuration file. Note that ASP.NET automatically decrypts configuration sections when processing them, and so you do not need to write any additional decryption code.

Summary of Steps

To encrypt configuration sections by using the DPAPI Data Protection provider, perform the following steps:
* Step 1: Identify the configuration sections to be encrypted
* Step 2: Choose the Machine or User store
* Step 3: Encrypt your configuration file data

Step 1: Identify the Configuration Sections to Be Encrypted

Encrypting and decrypting data has a performance overhead. To keep this overhead to a minimum, only encrypt the specific sections of your configuration file that store sensitive data.

Sections You Cannot Encrypt Using Protected Configuration

If you store sensitive data in any of the following configuration sections, you cannot encrypt it by using Protected Configuration and the Aspnet_regiis.exe tool.

<processModel>, <runtime>, <mscorlib>, <startup>, <system.runtime.remoting>, <protectedData>, <satelliteassemblies>, <cryptographySettings>, <cryptoNameMapping>, and <cryptoClasses>.

For the configuration sections listed above, you should use the Aspnet_setreg.exe tool, which is also available for earlier versions of the .NET Framework.

For more information about using the Aspnet_setreg tool to encrypt data in these configuration sections, see Microsoft Knowledge Base article 329290, "How to use the ASP.NET utility to encrypt credentials and session state connection strings" at http://support.microsoft.com/default.aspx?scid=kb;en-us;329290.

Step 2: Choose the Machine or User Store

The DataProtectedConfigurationProvider supports machine and user level stores for key storage. The choice of store is largely dependent on whether or not your application shares a server with other applications and whether or not sensitive data must be kept private to each application.

Machine Store

Use machine-level key storage in the following situations:
* Your application runs on its own dedicated server with no other applications.
* You have multiple applications on the same server that run using the same identity and you want those applications to be able to share sensitive information.

User Store

Use user-level key storage if you run your application in a shared hosting environment and you want to ensure that your application's sensitive data is not accessible to other applications on the server. In this scenario, each application should have a separate identity and the resources for the application such as files, and databases should be restricted to that identity.

Step 3: Encrypt Your Configuration File Data

This step shows you how to encrypt a connection string in Web.config. It shows you how to do this by using the machine store and then by using the user store.

Using DPAPI with the Machine Store to Encrypt a Connection String in Web.Config

The DataProtectionConfigurationProvider is configured to use DPAPI with the machine store by default.

To encrypt the connectionStrings section in Web.config:

1. Create a new Web site named MachineDPAPI. Make sure this directory is configured as a virtual directory.
2. Add a Web.config configuration file to this directory.
3. Add a sample connectionString like the one shown below.


		 <connectionStrings>
		  <add name="MyLocalSQLServer" 
		       connectionString="Initial Catalog=aspnetdb;data source=localhost;
	
Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
		 </connectionStrings>
	

4. Encrypt the connectionStrings section by running the following command from a command window.

		 aspnet_regiis -pe "connectionStrings" -app "/MachineDPAPI" 
		              -prov "DataProtectionConfigurationProvider"
	

Note that the above utility is located in the following directory.
		 [%WinDir%\Microsoft.NET\Framework\<versionNumber>]
	
* The -pe switch specifies the configuration section to encrypt.
* The -app switch specifies your Web application's virtual path. If it’s a nested application, you need to specify the nested path from the root directory, for example “/test/aspnet/MachineDPAPI”
* The -prov switch specifies the provider name.

If the command is successful, you will see the following output:

Encrypting configuration section...
Succeeded!

Note that the DPAPI machine key is stored at the following location.

		 %windir%\system32\Microsoft\Protect\S-1-5-18
	

5. Review Web.config and examine the changes. The following elements are created.

		 <protectedData>
		 [<protectedDataSections>]
		 [<EncryptedData>]
		 [<CipherData>]
	

Your modified Web.Config file, with the connectionStrings section encrypted should look similar to the following.

		 . . .
		 <protectedData>
		  [<protectedDataSections>]
		    <add name="connectionStrings" 
		         provider="dataprotectionconfigurationprovider"
		         inheritedByChildren="false" />
		  [</protectedDataSections>]
		 </protectedData>
		 . . .
		 <connectionStrings>
		  [<EncryptedData>]
		    [<CipherData>] 
	
<CipherValue>
AQAAANCMnd8BFdERjHoAwE/ClsBAAAAexuIJ/8oFEsGTs7jBKZdgQAAAACAAAAAAADZgAAqAAAABAAAAAKms84dyaCPAeaS
C1dIMIBAAAAAASAAACgAAAAEAAAAKaVI6aAOFdqhdc6w1Er3HMwAAAAcZ00MZOz1dI7kYRvkMIn/BmfrvoHNUwz6H9rcxJ6Ow
41E3hwHLbh79IUWiiNp0VqFAAAAF2sXCdb3fcKkgnagkHkILqteTXh
</CipherValue>
		    [</CipherData>]
		  [</EncryptedData>]
		 </connectionStrings>
		 . . .
	

6. Add the following Default.aspx Web page to your application's virtual directory and then browse to this page to verify the encryption and decryption works correctly.

		 <%@ Page Language="C#" %>
	

		 <script runat="server">
		    protected void Page_Load(object sender, [EventArgs] e)
		    {
		        Response.Write("Clear text connection string is: " + 
		                 [ConfigurationManager.ConnectionStrings]
		                            ["MyLocalSQLServer"].ConnectionString);
		    }
		 </script>
		 <html>
		  <body/>
		 </html>
	

MyLocalSQLServer is the name of the connection string you specified in Web.config earlier.

7. To revert the connectionStrings section to clear text, run the following command from the command prompt:

		 aspnet_regiis –pd "connectionStrings" –app "/MachineDPAPI"
	

If successful, the following output is produced.
Decrypting configuration section…
Succeeded!

Using DPAPI with a User Store to Encrypt a Connection String in Web.Config

Using the DataProtectionConfigurationProvider and DPAPI with the user store requires a small amount of additional configuration within Web.config.

To encrypt the connectionStrings section in Web.config:

1. Create a new Web site named UserDPAPI. Make sure this directory is configured as a virtual directory.
2. Add a Web.config configuration file to this directory.
3. Add a sample connectionString like the one shown below.

		 <connectionStrings>
		  <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb;
	
data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
		 </connectionStrings>
	

3. Add and configure a protected configuration provider to use the user store. To do so, add the following <protectedData> section. Note that you must set useMachineProtection=“false” to instruct the provider to use the user store. You must also use a unique provider name or a runtime error will be generated.

		 <protectedData>
		  <providers>
		    <add useMachineProtection="false" keyEntropy="" name="MyUserDataProtectionConfigurationProvider"
	
type="System.Configuration.DpapiProtectedConfigurationProvider, System.Configuration,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
		  </providers>
		 </protectedData>
	

4. Encrypt the connectionStrings section by running the following command from a command window.

		 Aspnet_regiis –pe "connectionStrings" –app "/UserDPAPI" 
		              -prov "MyUserDataProtectionConfigurationProvider"
	

* The –pe switch specifies the configuration section to encrypt.
* The –app switch specifies your Web application's virtual path. If it’s a nested application, you need to specify the nested path from the root directory, for example “/test/aspnet/UserDPAPI”
* The –prov switch specifies the provider name. In this case, this is set to “MyUserDataProtectionConfigurationProvider” which is the name you specified when configuring the provider in the previous step.

If the command is successful, you will see the following output:

Encrypting configuration section…
Succeeded!

Note that the DPAPI user key is stored in the following folder:

		 	\Documents and Settings\{UserName}\Application Data\Microsoft\Protect
	
\S-1-5-21-839522115-57989841-682003330-500

5. Review Web.config and examine the changes. The following elements are created.

		 [<protectedDataSections>]
		 [<EncryptedData>]
		 [<CipherData>]
	

Your modified Web.Config file, with the connectionStrings section encrypted should look similar to the following.

		 . . .
		 [<protectedDataSections>]
		   <add name="connectionStrings"
		        provider=" MyUserDataProtectionConfigurationProvider"
		        inheritedByChildren="false" />
		 [</protectedDataSections>]
		 . . .
	

		 <connectionStrings>
		  [<EncryptedData>]
		    [<CipherData>]
		     	[<CipherValue>]
	
AQAAANCMnd8BFdERjHoAwE/ClsBAAAAPt9Y22NmFk2V5dgs5/g7gAAAAACAAAAAAADZgAAqAAAABAAAAByM9
zHrBBxFC8WgkHdbnguAAAAAASAAACgAAAAEAAAAGhMcwDqOh3YHCU9tB3lwaCgAQAAL63mQfHOlzfWNCqCKjrOaBrSGC4e6I9n
L0ZZ2R3dm7gl6vZkWffpTsasnpzVsENuZNxGvsM7tdACp8AzOUcAVAiDNmqX1YcrWZ6NmxaVZoSH3shoSFqKweufsArXcV
1agQbVtH40miYn1lSUIk/bJIoir/oNckDxWbnT3QFRIvczy3rp3Ex33mnTxtrEXQ9S5yqFpJKLkWBDD0jiYExf73O/9yAZ5yig
CHzJscUsclFolLJBXz9acqbwdJHebTi/tGZ1p7gjrC+xMpDP9Zbu6S3oQdWFfItoeO16amwoZJARCsRvptF7qTkJJjhV7ZD1lnJ
oSP4lDLu7g0II3KhbFxwxB09Cv6QBb/5ZyEMGI04eDLBtH0X1kMwuvmJn27AjR7iXiFeRI7HryMBeuD+rr7FphpD9XsDY07GO
4DvVMdZZuVwM2c3E39U6cIphAxdrQS7HcaVZq4wa2M60xQaonDlPhQXlqvycu4O2LEvsoSMx//GeFZ6tlPwrsblLDYSgTEdtdQ
GupSiWezOxxSySluvRdqzpi8o6nkUAAAA8YNJo8x3Nh0a/q/YUpG6gBX0XQ=
</CipherValue>
		   [</CipherData>]
		  [</EncryptedData>]
		 </connectionStrings>
		 . . .
	

6. Add the following Default.aspx Web page to your application's virtual directory and then browse to this page to verify the encryption and decryption works correctly.

		 <%@ Page Language="C#" %>
	

		 <script runat="server">
		  protected void Page_Load(object sender, [EventArgs] e)
		  {
		    Response.Write("Clear text connection string is: " + 
		              [ConfigurationManager.ConnectionStrings]
		                         ["MyLocalSQLServer"].ConnectionString);
		  }
		 </script>
		 <html>
		  <body/>
		 </html>
	

MyLocalSQLServer is the name of the connection string you specified in Web.config earlier.
By default the ASP.NET applications run under the NT AUTHORITY \ Network Service account. When you access encrypted configuration sections using DPAPI with the user store, make sure that your application is running with the same user identity as the account you used to encrypt the data.
For example, by running the Aspnet_regiis command from the command line to encrypt data, the interactive account you used to logon to Windows is used to perform the encryption and the DPAPI key is maintained in that user's user profile. To ensure that the same account is used at runtime, you will need to configure your Web application in IIS to use Integrated Windows authentication and in Web.config you will need to enable impersonation as follows:

		 <system.web>
		  . . .
		  <identity impersonate="true" />
		  . . .
		 </system.web>
	

If your application runs under a different account than the one used to encrypt the data, ASP.NET will be unable to access the user store where the DPAPI key is held and the following error will be generated:

Failed to decrypt using provider 'MyUserDataProtectionConfigurationProvider'. Error message from the provider: Key not valid for use in specified state. (Exception from HRESULT: 0x8009000B)

7. To revert the connectionStrings section to clear text, run the following command from the command prompt:

		 aspnet_regiis -pd "connectionStrings" -app "/UserDPAPI"
	

If successful, the following output is produced.
Decrypting configuration section...
Succeeded!

Web Farm Scenarios

If you want to deploy the same encrypted configuration file on multiple servers in a Web farm, you should use the RSAProtectedConfigurationProvider. This provider makes it easy for you encrypt the data on one machine and then export the RSA private key needed to decrypt the data. You can then deploy the configuration file and the exported key to the target servers and then re-import the keys.
For more information, see "How To: Encrypt Configuration Sections in ASP.NET 2.0 with the RSA Provider."

Additional Resources

* HowToEncryptUsingRSA



Comments

<< Add your commments here - you need to login to Channel9 >>



Return to HomePage
Microsoft Communities