Managing Configuration Data Programmatically in ASP.NET 2.0
 
Published: 07 May 2008
Abstract
This article describes how to manage configuration data programatically through an ad hoc API in ASP.NET 2.0. After providing a brief introduction, Sanjit examines the usage and application of connection strings and encryption with the help of source code. Finally, you will learn the concepts involved with the configuration provider.
by SANJIT SIL
Feedback
Average Rating: 
Views (Total / Last 10 Days): 34566/ 92

Introduction

In ASP.NET 1.0 and 1.1 versions of the Framework provided API's that enabled us to only read information from the configuration file. There is no way to write information into the configuration file. However, ASP.NET 2.0 includes a full configuration management API that enables us to navigate, read and write an application's configuration file. Configuration settings are exposed as a set of strongly typed object against which we can easily program. The management API can be used to read and write configuration settings of remote and local applications. The WebConfigurationManager provides members (AppSettings, ConnectionStrings, OpenWebConfiguration, OpenMachineConfiguration, etc.) and using the methods of those members we can extract information from a configuration file. The sample code snippets have been written in C#.

AppSettings and Connection Strings

The sections that usually contain sensitive information that we 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.

The following code snippet displays all the keys of the appSettings section of the web.config file.

Listing 1

Configuration configuration = 
  WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath); 
AppSettingsSection appSettingsSection =
  (AppSettingsSection)configuration.GetSection("appSettings"); 
 if (appSettingsSection != null) 
  { 
   foreach (string key in appSettingsSection.Settings.AllKeys) 
    { 
      Response.Write(key); 
    } 
  } 

The following method can be used to update a specific key - value pair in the web.config file.

Listing 2

public void Update(string key, string value) 
{
Configuration configuration = 
  WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath); 
AppSettingsSection appSettingsSection = 
  (AppSettingsSection)configuration.GetSection("appSettings"); 
   if (appSettingsSection != null) 
   {
       appSettingsSection.Settings[key].Value = value; 
       config.Save();
   }
}

The following method can be used to delete a specific key in the web.config file.

Listing 3

public void Delete(string key) 
{
Configuration configuration = 
  WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath); 
AppSettingsSection appSettingsSection = 
  (AppSettingsSection)configuration.GetSection("appSettings"); 
  if (appSettingsSection != null) 
  { 
     appSettingsSection.Settings.Remove(key); 
     config.Save();
  } 
}
Using Encryption

Encrypting an entire section of a configuration file is a simple task with the .NET 2.0 configuration API. There are many configuration areas where sensitive and secret information may appear; for example, we can put database usernames and passwords in the <connectionStrings>, when we need the runtime to impersonate a fixed identity we often keep a username and password in the <identity> section. Whenever secrets like these appear, we should consider encrypting the section instead of leaving the secrets and sensitive information in plain text.

It should be noted that the following sections can not be encrypted using protected configuration:

<processModel>

<runtime>

<mscorlib>

<startup>

<system.runtime.remoting>

<configProtectedData>

<satelliteassemblies>

<cryptographySettings>

<cryptoNameMapping>

<cryptoClasses>

We have to use the Aspnet_setreg.exe tool if we want to encrypt the abovementioned section. This tool we can find under the ASP.NET installation path. It is really easy to protect (encrypt) and unprotect (decrypt) an entire configuration section. We do not need to decrypt a section in order to read configuration settings from the section. The runtime will read the encrypted data and perform the decryption necessary for our application to read the plain text values. In the following code listing we will see how we can encrypt a section data and decrypt the same using WebConfigurationManager - related classes.

Listing 4

<appSettings>
  <add key="Confidentialkey" value="sanjit9999900000000" />
</appSettings> 

To illustrate the encrypt and decrypt data in section two buttons namely btnEncrypt and btnDecrypt are added in a test page:

Listing 5

protected void  btnEncrypt_Click(object sender, EventArgs e)
{
        Encrypt("appSettings",
        "DataProtectionConfigurationProvider");
 
}
protected void  btnDecrypt_Click(object sender, EventArgs e)
{
        Decrypt("appSettings");
}
 
 
private void Encrypt(string sectionName,
                                   string provider)
{
    Configuration config =
        WebConfigurationManager.
            OpenWebConfiguration(Request.ApplicationPath);
 
    ConfigurationSection section =
                 config.GetSection(sectionName);
 
    if (section != null &&
              !section.SectionInformation.IsProtected)
    {
        section.SectionInformation.ProtectSection(provider);
        config.Save();
    }
}
 
private void Decrypt(string sectionName)
{
    Configuration config =
        WebConfigurationManager.
            OpenWebConfiguration(Request.ApplicationPath);
 
    ConfigurationSection section =
              config.GetSection(sectionName);
 
    if (section != null &&
          section.SectionInformation.IsProtected)
    {
        section.SectionInformation.UnprotectSection();
        config.Save();
    }
}

So there is two buttons which are showing how to encrypt and decrypt section data on fly.

In the following code listing we can see how the application setting data looks like after encryption.

Listing 6

<appSettings configProtectionProvider="DataProtectionConfigurationProvider"> 
<EncryptedData>
<CipherData> 
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA73ohmg84YUKbVjbcXs6jCQQAAAACAAAAAAADZ
gAAqAAAABAAAAD6QbBeUN2Ri0Rjc+jxzF/bAAAAAASAAACgAAAAEAAAAAKUxQ1g3ZGpRK0PVCmG717AAAA
Aj7x96pMed9vhi7reOt765j6u/0rxcA3GW8XWT8M5ejtW9zuNMI4K0Hx+2IU/1Q9ZY1tSn+nv1WWCUsAr2
w0be1CCY5aWBFe/QQssnpUTrRVAPa+W7VyTQ+HJDWiH1NKuu63OLpmEqBCXe4EUJC42UaGHUV5bCKYaSgM
XeP+QKjR46AkOLmMod8SxrA2moOvIbIRIduufv0d5eRKj0AgSFLtOPECj7NeRfXce/FqLelQno0ZSSQ0xd
yGnq07O6YbHFAAAACPjEY/EbhvBAwnuR/yG/2p7In1w</CipherValue>
</CipherData>
</EncryptedData>
</appSettings>

Listing 7

<connectionStrings>
    <add name="pubs" 
      connectionString="localhost;integrated security=true;database=pubs;" />
  </connectionStrings>

The above code listing is showing connectionStrings related data before encryption.

In the following code listing we can see how connectionStrings related data looks like after encryption. We can notice that the configuration API has added some additional information and the section contains a cipher Value instead of plain text connection strings

Listing 8

<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
    <EncryptedData>
      <CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA73ohmg84YUKbVjbcXs6jCQQAAAACAAAAAAADZ
gAAqAAAABAAAAAwxh6BaZAyLKa8vBjTomZkAAAAAASAAACgAAAAEAAAAFRvsDBGI7d90o/cWOUoGPAQAQA
AeCkgDXGISNyrSJfVCWz+t7WU9lf1gkupFRFJYfebeEIzjfTHQ/MC6SD75t0qgrE89LbHpDgstfMxpxUSn
QZ1ep9V5ZmoLOwf+DyBeIlsIb5hw4k8MQwORuSXABtO5xfDTJEd/kaFtIFnzfAjx/nbGXx2HNu5YzXkQ7V
5BaK44Jd3R44jTl8dqMcWLZsUdKj4dy/PiXLr+qCfpkKUeGZKnSAPwjoFZ8a6BKs0rAhNWl6k6Pev+/tuL
cyOlYZhJ7CXLgKGq4dEM4e8bYs7EwJMvKR/GbHmhkoFSQKu1orQI/Sv6c0Anyggy/riaRRb6N2nksa2mO4
OMdZfI5z/uh5HA0JxZSQ+P7G8BeuGKoPfiL0UAAAAVZyDYYrci5shlEyvRHo0IIRxMtI=</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>
 

It should be noted that we cannot tell anything about the encrypted data, including the number of settings, the key names of settings, or their data types.

Configuration provider

To understand what we are seeing in the configuration file, we first need to realize that the runtime turns to a configuration encryption provider for encryption and decryption work. The two providers shipping in .NET 2.0 are the DataProtectionConfigurationProvider and the RSAProtectedConfigurationProvider.

The purpose of an encryption provider is quiet simple - encrypt the contents of the specified section using a particular cryptographic engine and return the results as an XML node. Likewise, the provider must be able to decrypt the contents of a given XML node.

We can specify the provider we want to use in the string passed to the Encrypt method, as we have seen in the abovementioned code snippet. In our example we are using the DataProtectionConfigurationProvider.

The DataProtectionConfigurationProvider uses the Windows Data Protection API (DPAPI). This provides a machine-specific secret key for encryption and decryption work. Because the DataProtectionConfigurationProvider relies on a machine-specific key, we can only decrypt cipher text that was encrypted on the same machine; that means we can not use a configuration file encrypted in this way on any other computer.

If we need to move configuration files with encrypted sections from machine to machine, we need the RSAProtectedConfigurationProvider. We can copy this key between computers. The RSAProtectedConfigurationProvider, as the name would imply, uses RSA public key encryption. The RSA provider is used by default. However, if we do not want to write code, we can use the command line tool aspnet_regiis. Even though building our own custom provider is possible, the golden rule as far as encryption is concerned is, "Do not build your own encryption library, but use any reliable library that exists."

References

Conclusion

Although, ASP.NET is configured to reject all HTTP requests for resources with .config extension, if the malicious user still gains access to web server's file system then sensitive information in configuration file will be disclosed. It is fortunate that ASP.NET 2.0 mitigates this problem by introducing encryption schemes for configuration files. We can either encrypt or decrypt configuration files including Web.config and Machine.config either programmatically or using aspnet_regiis.exe tool. We can read and write configuration files for our application, for another application on the same machine, or even an application on a different server. Even though it is a nice feature to modify web.config file programmatically, it is not recommended to do so frequently in a Web application because any change in the web.config file will restart the Web server and refresh the cache entries. Hence, we should consider the same before modifying config file. Moreover, encrypting and decrypting data incurs performance overhead. We should encrypt only the sections of our configuration file that store sensitive data to keep this overhead to a minimum.



User Comments

No comments posted yet.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2018 ASPAlliance.com  |  Page Processed at 2018-11-14 9:27:52 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search