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

 

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

patterns & practices Developer Center

patterns & practices Developer Center

J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley

Microsoft Corporation

July 2005

Applies To

  • ASP.NET version 2.0
  • Microsoft® Windows Server™ 2003 operating system

Summary

This How To shows how to use the Windows Data Protection application programming interface (DPAPI) protected configuration provider and the Aspnet_regiis.exe tool to encrypt sections of your configuration files. You can use the Aspnet_regiis.exe tool to encrypt sensitive data, such as connection strings, held in the Web.config and Machine.config files. The DPAPI protected configuration provider supports machine-level and user-level stores for key storage. The choice of store depends largely on whether or not your application shares a server with other applications and whether or not sensitive data must be kept private for each application. Note that if your application is deployed in a Web farm, you should use the RSA protected configuration provider due to the ease with which RSA keys can be exported.

Contents

Objectives
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

Objectives

  • Learn about key changes for encrypting sensitive data in configuration files in ASP.NET version 2.0.
  • Know which sections can and cannot be encrypted with the DPAPI protected configuration provider.
  • Choose between user-level and machine-level DPAPI key storage.
  • Use the DPAPI protected configuration provider to encrypt sections of your configuration file.
  • Learn about the Web farm restrictions.

Overview

Configuration files such as the Web.config file are often used to hold sensitive information, including user names, passwords, database connection strings, and encryption keys. If you do not protect this information, your application is vulnerable to attackers or malicious users obtaining sensitive information such as account user names and passwords, database names and server names. The sections that usually contain sensitive information that you need to encrypt are the following:

  • <appSettings>. This section contains custom application settings.
  • <connectionStrings>. This section contains connection strings.
  • <identity>. This section can contain impersonation credentials.
  • <sessionState>. The section contains the connection string for the out-of-process session state provider.

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

What's New in 2.0

.NET Framework versions 1.0 and 1.1 had limited support for configuration file encryption. However, .NET Framework 2.0 introduces a protected configuration feature that allows you to encrypt sensitive configuration file data by using a command line tool. The following two protected configuration providers are included, 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.
  • DataProtectionConfigurationProvider. This provider uses DPAPI to encrypt and decrypt data.

This How To explains how to use the Aspnet_Regiis.exe tool with the DataProtectionConfigurationProvider and DPAPI to encrypt sections of your configuration file.

Note   ASP.NET automatically decrypts configuration sections when processing them; therefore, 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 incurs performance overhead. To keep this overhead to a minimum, encrypt only the 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>
  • <configProtectedData>
  • <satelliteassemblies>
  • <cryptographySettings>
  • <cryptoNameMapping>
  • <cryptoClasses>

For the configuration sections listed, you should use the Aspnet_setreg.exe tool, which is also available for previous 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.

Step 2. Choose the Machine or User Store

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

Note   For information on where the user key is stored, see: Windows Data Protection.

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 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 make sure that your application's sensitive data is not accessible to other applications on the server. In this situation, each application should run under 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 the Web.config file, first with the machine store and then with the user store.

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

By default, the DataProtectionConfigurationProvider is configured to use DPAPI with the machine store.

To encrypt the connectionStrings section in Web.config

  1. Create a new Web site named MachineDPAPI. Make sure that this directory is configured as a virtual directory.

  2. Add a Web.config configuration file to this directory.

  3. Add a sample connectionString similar to the following example.

    <connectionStrings>
      <add name="MyLocalSQLServer" 
           connectionString="Initial Catalog=aspnetdb;
           data source=localhost;Integrated Security=SSPI;" 
           providerName="System.Data.SqlClient"/>
    </connectionStrings>
    
    
  4. To encrypt the connectionStrings section, run the following command from a .NET command prompt:

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

The above command with the -app switch assumes that there is an IIS virtual directory called MachineDPAPI. If you are using the Visual Studio .NET 2005 Web server instead of IIS, use the -pef switch, which allows you to specify the physical directory location of your configuration file.

aspnet_regiis.exe -pef "connectionStrings" C:\Projects\MachineDPAPI –prov "DataProtectionConfigurationProvider"

Note   The Aspnet_regiis.exe utility tool is located in the following directory:

%WinDir%\Microsoft.NET\Framework\<versionNumber>

  • The -pe switch specifies the configuration section to encrypt.

  • The -pef switch specifies the configuration section to encrypt and allows you to supply the physical directory path for your configuration file.

  • The -app switch specifies your Web application's virtual path. If it is 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   The DPAPI machine key is stored at the following location:

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

  1. Review the Web.config file, and examine the changes. The following elements are created:

    • <EncryptedData>
    • <CipherData>
    • <CipherValue>

    Your modified Web.config file, with the connectionStrings section encrypted, should be similar to the following example.

    ...
    <connectionStrings configProtectionProvider="DataProtectionConfigurationProvider"> 
      <EncryptedData>
        <CipherData>
    <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAexuIJ/8oFE+sGTs7jBKZdgQAAAACAAAAAAADZgAAqAAAABAAAAA
    Kms84dyaCPAeaSC1dIMIBAAAAAASAAACgAAAAEAAAAKaVI6aAOFdqhdc6w1Er3HMwAAAAcZ00MZOz1dI7kYRvkMIn/
    BmfrvoHNUwz6H9rcxJ6Ow41E3hwHLbh79IUWiiNp0VqFAAAAF2sXCdb3fcKkgnagkHkILqteTXh</CipherValue>
        </CipherData>
      </EncryptedData>
    </connectionStrings>
    ...
    
  2. Add the following Default.aspx Web page to your application's virtual directory, and then browse to this page to verify that encryption and decryption worked correctly.

    <%@ Page Language="C#" %>
    
    <script >
        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 that you previously specified in the Web.config file.

  3. To change the connectionStrings section back to clear text, run the following command from the command prompt:

    aspnet_regiis -pd "connectionStrings" -app "/MachineDPAPI"

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

    Decrypting configuration section...
    Succeeded!
    

To decrypt the connectionStrings section specifying a physical path to your application's configuration file, use the -pdf switch as shown here.

aspnet_regiis -pdf "connectionStrings" C:\Projects\MachineDPAPI

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

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.

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

To encrypt the connectionStrings section in Web.config

  1. Create a new Web site named UserDPAPI. Make sure that this directory is configured as a virtual directory.

  2. Add a Web.config configuration file to this directory.

  3. Add a sample connectionString similar to the following example.

    <connectionStrings>
      <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb;
    data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
    </connectionStrings>
    
    
  4. Add and configure a protected configuration provider to use the user store. To do this, add the following <configProtectedData> section. You must set useMachineProtection= "false" to instruct the provider to use the user store. You must also use a unique provider name, or a run-time error will occur.

    <configProtectedData>
      <providers>
        <add useMachineProtection="false" keyEntropy="" name="MyUserDataProtectionConfigurationProvider" 
    type="System.Configuration.DpapiProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, 
    PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </configProtectedData>
    
    
  5. Run the following command from a command prompt to encrypt the connectionStrings section:

    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 is 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 step 3.

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

    Encrypting configuration section...
    Succeeded!
    

    Note   For information on where the user key is stored, see: https://msdn.microsoft.com/en-us/library/ms995355.aspx

Because your application must access the data by using the same identity that you used to encrypt the data, you may need to run the encryption command using your application's service account identity. To do so, you can start a command window by using the runas command, specifying an appropriate domain and user name, as follows:

Runas /profile /user:domain\user cmd

When you run Aspnet_regiis from the resulting command window, it will use the specified identity to perform the encryption. This enables your application that uses the same identity to decrypt the data at run time.

  1. Review the Web.config file, and examine the changes. The following elements are created:

    • <EncryptedData>
    • <CipherData>
    • <CipherValue>

    Your modified Web.config file, with the connectionStrings section encrypted should be similar to the following example.

    ...
    <connectionStrings configProtectionProvider="MyUserDataProtectionConfigurationProvider">
        <EncryptedData>
          <CipherData>
            <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAWuizHyLxzk+U4/8NnMRAjQAAAAACAAAAAAADZgAAqAAAABAAAADLFqu00qT0BeGh6wmHHGySAAAAAASAAACgAAAAEAAAAM56z6ezglmufZGcta83RKGgAQAAtvDpExhD6h95lfWBt0FqZYzxupI2IepH/XlhLB5rsuuQDCJUL7XGIIsaVW2oNQxgNCPXxRSuCxHQ7vqgbh4G7xHk0wdyws5Ax4T/RYJbfYEF5KAPzShdmdoZdkY/FOWrVEgAr7LzKFBoDcPJBvgX+lfsJdBNeWRB5BqRX552dUFjtDlp8u3K/dA9twWDU2w/cRLMXJtVZ/y/ICI1fzXjX3u7sY9K1IC+5Hbi7nouCK6Ze5RLBnL0Zfdq0PyGlj2To4ftAYAT0SzkBaxlXRQSzMhX+7c+rgKpMqtG9XjAW26x3IJAp2/uAr2zOZqH+tskamHYSruhTicHJDTtP+r6Rs21y2QkRT9Hb9oPd9B5mDIzGtDkifWBbmwLv4XFuYcna1Zgny7McSxMI62jxayVlZKcS5dXV0shwLoUjbTDcXQmFKsRvo2sCW86wcN8ad02jhKCQMf9SWnZpd849mlqgMFiQQSFlZ6Q+vJLrXqVb8zmVZemQPQcY/DktgjOvjn0iOZ3zhl20fRENOa3ZIWvvK8p9pblz3sEfS19MAW0JtYUAAAAayvNPot3An7LaCTdFYrEip+fTU4=</CipherValue>
          </CipherData>
        </EncryptedData>
      </connectionStrings>
    ...
    
  2. Add the following Default.aspx Web page to your application's virtual directory, and then browse to this page to verify that encryption and decryption work correctly.

    <%@ Page Language="C#" %>
    
    <script >
      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 that you previously specified in the Web.config file.

    Then, in the Web.config file, you need to enable impersonation as shown in the following example.

    <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 will generate the following error:

    Failed to decrypt using provider 'MyUserDataProtectionConfigurationProvider'.
     Error message from the provider: Key not valid for use in specified state. 
    (Exception from HRESULT: 0x8009000B)
    
    
  3. To change the connectionStrings section back to clear text, run the following command from the command prompt:

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

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

    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 server computer 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 Using RSA.

Additional Resources

Feedback

Provide feedback by using either a Wiki or e-mail:

We are particularly interested in feedback regarding the following:

  • Technical issues specific to recommendations
  • Usefulness and usability issues

Technical Support

Technical support for the Microsoft products and technologies referenced in this guidance is provided by Microsoft Support Services. For product support information, please visit the Microsoft Support Web site at https://support.microsoft.com

Community and Newsgroups

Community support is provided in the forums and newsgroups:

To get the most benefit, find the newsgroup that corresponds to your technology or problem. For example, if you have a problem with ASP.NET security features, use the ASP.NET Security forum.

Contributors and Reviewers

  • External Contributors and Reviewers: Andy Eunson; Manoranjan M. Paul; Rudolph Araujo, Foundstone Professional Services
  • Microsoft Services and PSS Contributors and Reviewers: Aaron Margosis, Denny Dayton, Tom Christian, Wade Mascia, Adam Semel
  • Microsoft Product Group Contributors and Reviewers: Stefan Schackow, Vikas Malhotra
  • Test team: Larry Brader, Microsoft Corporation; Nadupalli Venkata, Surya Sateesh, Sivanthapatham Shanmugasundaram, Infosys Technologies, Ltd.
  • Edit team: Nelly Delgado, Microsoft Corporation; Tina Burden McGrayne, Linda Werner & Associates, Inc.
  • Release Management: Sanjeev Garg, Microsoft Corporation.

patterns & practices Developer Center

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.