Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication

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

How To: Use DPAPI (Machine Store) from ASP.NET 1.1

J.D. Meier, Alex Mackman, Michael Dunner, and Srinath Vasireddy
Microsoft Corporation

Published: November 2002

Last Revised: January 2006

Applies to:

  • ASP.NET 1.1

See the "patterns & practices Security Guidance for Applications Index" for links to additional security resources.

See the Landing Page for a starting point and complete overview of Building Secure ASP.NET Applications.

Summary: This How To shows you how to use DPAPI from an ASP.NET Web application or Web service to encrypt sensitive data. (7 printed pages)

Contents

Notes
Summary of Steps Step 1. Create an ASP.NET Client Web Application Step 2. Test the Application Step 3. Modify the Web Application to Read an Encrypted Connection String from Web.Config
Additional Resources

Web applications often need to store security-sensitive data, such as database connection strings and service account credentials in application configuration files. For security reasons, this type of information should never is stored in plain text and should always be encrypted prior to storage.

This How To describes how to use DPAPI from ASP.NET. This includes ASP.NET Web applications, Web services, and .NET Remoting components that are hosted in ASP.NET.

Notes

  • DPAPI can work with either the machine store or user store (which requires a loaded user profile). DPAPI defaults to the user store, although you can specify that the machine store be used by passing the CRYPTPROTECT_LOCAL_MACHINE flag to the DPAPI functions.

  • The user profile approach affords an additional layer of security because it limits who can access the secret. Only the user who encrypts the data can decrypt the data. However, use of the user profile requires additional development effort when DPAPI is used from an ASP.NET Web application because you need to take explicit steps to load and unload a user profile (ASP.NET does not automatically load a user profile).

  • The machine store approach (adopted in this How To) is easier to develop because it does not require user profile management. However, unless an additional entropy parameter is used, it is less secure because any user on the computer can decrypt data. (Entropy is a random value designed to make deciphering the secret more difficult.) The problem with using an additional entropy parameter is that this must be securely stored by the application, which presents another key management issue.

    Note   If you use DPAPI with the machine store, the encrypted string is specific to a given computer and therefore you must generate the encrypted data on every computer. Do not copy the encrypted data across computers in a farm or cluster.

  • For a related article that shows how to use DPAPI with the user store from an ASP.NET Web application (by using a serviced component within an Enterprise Services application), see How To: Use DPAPI (User Store) from ASP.NET 1.1 with Enterprise Services within the Reference section of this guide.

Summary of Steps

This How To includes the following steps:

  • Step 1. Create an ASP.NET Client Web Application
  • Step 2. Test the Application
  • Step 3. Modify the Web Application to Read an Encrypted Connection String from Web.Config

Step 1. Create an ASP.NET Client Web Application

This procedure creates an ASP.NET client Web application that will call the DPAPI class library to encrypt and decrypt data stored within the Web.config file.

To create an ASP.NET client Web application

  1. Start Microsoft® Visual Studio® .NET and create a new C# ASP.NET Web application called DPAPIClientWeb.

  2. Add a reference to the DataProtector.dll assembly, previously created in "How To: Create a DPAPI Library in.NET 1.1."

  3. Open WebForm1.aspx.cs and add the following using statements to the top of the file beneath the existing using statements.

    using System.Text;
    using DataProtection;
    
  4. Add the controls listed in Table 1 to WebForm1.aspx.

    Table 1: WebForm1.aspx controls

    Control Type Text ID
    Button Encrypt btnEncrypt
    Button Decrypt btnDecrypt
    TextBox   txtDataToEncrypt
    TextBox   txtEncryptedData
    TextBox   txtDecryptedData
    Label   lblError
    Label Data To Encrypt  
    Label Encrypted Data  
    Label Decrypted Data  

    Your Web form should look similar to Figure 1.

    Ff649248.fh8sn01(en-us,PandP.10).gif

    Figure 1. DPAPIClientWeb Web Form

  5. Double-click the Encrypt button to create a button click event handler.

    DataProtector dp = new DataProtector( 
      DataProtector.Store.USE_MACHINE_STORE );
    try
    {
      byte[] dataToEncrypt = 
        Encoding.ASCII.GetBytes(txtDataToEncrypt.Text);
      // Not passing optional entropy in this example
      // Could pass random value (stored by the application) for added
      // security when using DPAPI with the machine store.
      txtEncryptedData.Text =
                Convert.ToBase64String(dp.Encrypt(dataToEncrypt,null));
    }
    catch(Exception ex)
    {
      lblError.ForeColor = Color.Red;
      lblError.Text = "Exception.<br>" + ex.Message;
      return;
    }
    lblError.Text = "";
    
  6. Return to the Web form and double-click the Decrypt button. Add the following code to the button click event handler.

    DataProtector dp = new 
      DataProtector(DataProtector.Store.USE_MACHINE_STORE);
    try
    {
      byte[] dataToDecrypt = 
        Convert.FromBase64String(txtEncryptedData.Text);
      // Optional entropy parameter is null. 
      // If entropy was used within the Encrypt method, the same entropy
      // parameter must be supplied here
      txtDecryptedData.Text = 
              Encoding.ASCII.GetString(dp.Decrypt(dataToDecrypt,null));
    }
    catch(Exception ex)
    {
      lblError.ForeColor = Color.Red;
      lblError.Text = "Exception.<br>" + ex.Message;
      return;
    }
    lblError.Text = "";
    
  7. On the Build menu, click BuildSolution.

Step 2. Test the Application

This procedure tests the Web application to confirm that data is successfully encrypted and decrypted.

To test the application

  1. Press Ctrl+F5 to run the Web application.

  2. Enter a string in the Data to Encrypt text box and click Encrypt.

    Confirm that encrypted data (in Base64 encoded format) is displayed in the EncryptedData text box.

  3. Click the Decrypt button.

    Confirm that the encrypted data is successfully decrypted and displayed in the DecryptedData text box.

Step 3. Modify the Web Application to Read an Encrypted Connection String from Web.Config

This procedure takes an encrypted database connection string and places the encrypted cipher text into the application's Web.config file within an <appSettings> element. You will then add code to read and decrypt this string from the configuration file.

To modify the Web application to read an encrypted connection string from Web.config

  1. Return to Visual Studio .NET and display the WebForm1.aspx in Designer mode.

  2. Add another button to the form. Set its Text property to Decrypt string from config file and its ID property to btnDecryptConfig.

  3. Double-click the button to create a button click event handler.

  4. Add the following using statement to the top of the file beneath the existing using statements.

    using System.Configuration;
    
    
  5. Return to the btnDecryptConfig_Click event handler and add the following code to retrieve a database connection string from the <appSettings> section of the Web.config file.

    DataProtector dp = new 
      DataProtector(DataProtector.Store.USE_MACHINE_STORE);
    try
    {
      string appSettingValue =
                ConfigurationSettings.AppSettings["connectionString"];
      byte[] dataToDecrypt = Convert.FromBase64String(appSettingValue);
      string connStr = Encoding.ASCII.GetString(
                                   dp.Decrypt(dataToDecrypt,null));
      txtDecryptedData.Text = connStr;
    }
    catch(Exception ex)
    {
      lblError.ForeColor = Color.Red;
      lblError.Text = "Exception.<br>" + ex.Message;
      return;
    }
    lblError.Text = "";
    
  6. On the Build menu, click BuildSolution to rebuild the projects.

  7. Right-click WebForm1.aspx, and then click View in Browser.

  8. Enter a database connection string such as the one that follows into the Data to Encrypt field.

    server=(local);Integrated Security=SSPI; database=Northwind
    
  9. Click the Encrypt button.

  10. Select the encrypted cipher text and copy it to the clipboard.

  11. Switch to Visual Studio .NET, open Web.config and add the following <appSettings> element outside of the <system.web> element. Assign the encrypted connection string currently on the clipboard to the value attribute.

    <appSettings>
       <add key="connectionString" value="encrypted connection string"
         />
    </appSettings>
    
  12. Save Web.config.

  13. Click the Decrypt string from config file button and confirm that the encrypted database connection string is successfully read from the Web.config file and that the decrypted connection string is successfully displayed in the Decrypted data field.

Additional Resources

For more information, see the following related How Tos in the Reference section of this guide:

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.

© Microsoft Corporation. All rights reserved.