Software Development

Encrypting .NET configuration files through code


Encryption support for configuration files was added to the .NET Framework beginning with version 2.0. Last week's article focused on using ASP.NET command-line tools for encrypting portions of configuration files, while this week's article covers coding options. The .NET Framework libraries include full support for controlling encryption and decryption in code. I include examples in both VB.NET and C# to demonstrate the encrypting and decryption of configuration file sections.

Protect sensitive data

Encrypting configuration data improves application security by making it difficult for users to view the data even if they access the configuration file. There are two protected configuration providers included with ASP.NET: RSAProtectedConfigurationProvider and DPAPIProtectedConfigurationProvider. RSAProtectedConfigurationProvider uses the RSACryptoServiceProvider to encrypt configuration sections using RSA public key encryption to encrypt and decrypt data. DPAPIProtectedConfigurationProvider uses the Windows Data Protection API (DPAPI) to encrypt configuration sections using the built-in cryptography capabilities of Windows. You can also create your own protected settings providers if needed. While a user will have a hard time dealing with encrypted data, ASP.NET has no problems. You can use both of these providers in ASP.NET code.

Using code

The .NET Framework 2.0 allows you to encrypt most configuration sections within the Web.config or machine.config files. The System.Web.Configuration namespace is used to encrypt configuration files via code. It contains two methods associated with encryption: ProtectSection and UnprotectSection.

  • ProtectSection: Marks a configuration section for protection. The name of the provider to be used for the encryption is passed to the method as its only parameter (a string value).
  • UnprotectSection: Removes the protected configuration encryption from the associated configuration section. It has no parameters.

As an example, the following simple ASP.NET web.config file demonstrates encryption and decryption of configuration data:

<?xml version="1.0"?>

<configuration>

<appSettings/>

<connectionStrings>

<add name="db" connectionString="connection details" />

</connectionStrings>

<system.web>

<compilation debug="false" />

<authentication mode="Windows" />

</system.web>

</configuration>

The following VB.NET code from an ASP.NET Web form encrypts the connectionStrings section of the file:

Public Sub Page_Load()

Dim config As Configuration

Dim configSection As ConfigurationSection

config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)

If Not (config Is Nothing) Then

configSection = config.GetSection("connectionStrings")

If Not (configSection Is Nothing) Then

If Not (configSection.SectionInformation.IsLocked) Then

configSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")

config.Save()

End If

End If

End If

End Sub

The code performs the following steps:

  • It uses the System.Web.Configuration namespace to work with the necessary classes.
  • It accesses the application's web.config file via the OpenWebConfiguration method of the WebConfigurationManager class.
  • It accesses the connectionStrings section of the web.config file via the GetSection method.
  • The section is encrypted using the default Windows encryption scheme if the file is not locked.
  • The changes to the file are saved.

The equivalent C# code follows.

protected void Page_Load(object sender, EventArgs e) {

Configuration config;

ConfigurationSection configSection;

config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

configSection = config.GetSection("connectionStrings");

if (configSection != null) {

if (!(configSection.SectionInformation.IsLocked)) {

configSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");

config.Save();

} } }

Once the code runs, the connectionStrings section of my web.config now appears like the following:

<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">

<EncryptedData>

<CipherData>

<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAaZ2eussTfEmhwe+kgLsWVwQAAAACAAAAAAADZgAAqAAAABAAAADnyhn4dHzOLGFsIj8QUrXgAAAAAASAAACgAAAAEAAAAKFRR3MAelpxxV6J+KEhfqnQAAAAFJOBaI5ciKhw3Ywra+G0hkZb67k0YTJmXYe5+5cpZ3Wd3H2696mEhAGQiTecOVGixqtF9lHa+QipmMSHcVECiWYjOh/6CIQL6GED37erb4TLZSNo4U7FrE2JscNCnKaKZUtvnxVqRmjcDWU7Gm2rYRAHoDSEy0UE7ebbcqr7LQ+Y+C7WrFk+VKf6NmN4js4vl7TJXl/Nr36Z65bvZDCxcle66rZ2yebtXMTP2bX95NasbQx0trvnjJrdIdMMrLOqLDPhQLwZ4ObCxkh+Rlg4NxQAAABU+1akHFhrg+4d0AmCGE8Egt3HrA==</CipherValue>

</CipherData>

</EncryptedData>

</connectionStrings>

The following VB.NET code decrypts the section and displays its value:

Public Sub Page_Load()

Dim config As Configuration

Dim configSection As ConfigurationSection

config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)

configSection = config.GetSection("connectionStrings")

If Not (configSection Is Nothing) Then

If Not (configSection.SectionInformation.IsLocked) Then

configSection.SectionInformation.UnprotectSection()

config.Save()

End If

End If

End Sub

The code follows the same flow as the encrypt example with the lone exception of being the call to the UnprotectSection method to decrypt the specific section. The equivalent C# code follows:

protected void Page_Load(object sender, EventArgs e) {

Configuration config;

ConfigurationSection configSection;

config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

configSection = config.GetSection("connectionStrings");

if (configSection != null) {

if (!(configSection.SectionInformation.IsLocked)) {

configSection.SectionInformation.UnprotectSection();config.Save();

} } }

Encrypting non-Web applications

The .NET Framework supports also this type of encryption with configuration files for non-ASP.NET applications. For instance, the System.Configuration namespace includes encryption support. It follows the same approach as the previous ASP.NET examples except the Configuration class from the System.Configuration namespace is used to gain access to the configuration file. The following VB.NET code demonstrates working with an application's app.config file:

Dim config As System.Configuration.Configuration =         ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)

Dim configSection ConfigurationSection

configSection = config.ConnectionStrings

If Not (configSection Is Nothing) Then

If Not (configSection.ElementInformation.IsLocked) Then

configSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")

configSection.SectionInformation.ForceSave = True

config.Save(ConfigurationSaveMode.Full)

End If

End If

The section is easily decrypted with the following VB.NET code:

Dim config As System.Configuration.Configuration =         ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)

Dim configSection ConfigurationSection

configSection = config.ConnectionStrings

If Not (configSection Is Nothing) Then

If Not (configSection.ElementInformation.IsLocked) Then

configSection.SectionInformation.UnprotectSection()

configSection.SectionInformation.ForceSave = True

config.Save(ConfigurationSaveMode.Full)

End If

End If

Performance

As with everything that adds security, encrypting and decrypting configuration file sections adversely affects performance. You should test an application both with and without encryption to determine the effects for certain applications. With that said, you should only encrypt what is necessary, such as only those configuration sections that contain sensitive information like connection string and user information.

Don't make it easy

Encryption provides another roadblock for malicious users looking to gain access to sensitive information. The .NET Framework allows you to easily encrypt and decrypt configuration files using built-in or custom encryption schemes.

What kind of data do you store in configuration files? Have you used other encryption schemes in the past to hide the information? Share your experience and thoughts with the .NET community.

Tony Patton began his professional career as an application developer earning Java, VB, Lotus, and XML certifications to bolster his knowledge.

---------------------------------------------------------------------------------------

Get weekly .NET tips in your inbox
TechRepublic's free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically subscribe today!

About

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

8 comments
abhilashca
abhilashca

Hi, Its a handy article. But, i jumped into a problem. I copied the code exactly as above, but its not working for me. Nothing is encrypting. Im using VWD 2008 Express Edition. Or is it, since i'm using file-system other than iis, for development. Can anyone help me. Thankz

psmith
psmith

Tony Patton writes in an excellent style that I find easy to learn with. I am going to search to see if he has a blog.

jausions
jausions

Now, for Windows Forms application the built-in encryption providers are pointless when dealing with applications shared by multiple users on the same machine. Since the encryption now needs to be done with machine keys, someone can create another application to read the app.config and voila not so secure anymore. Several articles on the web try to deal with this by encrypting during the installation process, but that method is not compatible with ClickOnce deployment. I'm still trying to figure out how to provide a custom config section encryption provider...

aherring
aherring

Any ideas on how to do this on site not allowing write access to the web.config file? (Using forms authentication, the network service account doesn't have write access to the root folder nor the web.config by default.) Thanks

odis
odis

Can you provide C# code for Encrypting non-Web applications?

Justin James
Justin James

Tony - I like this follow up article. I had a few questions, though: * What is the performance hit for this? Encryption is typically a bit of math to perform. If many frequently hit pages have to do this on every page load, it could be a significant decrease in performance. * Can the decrypted information be securely stored in the ASP.Net caching components, with a file dependency, to eliminate the need to decrypt each time the data is needed? Or do you see the cache as being a potentially insecure place to put that data? Thanks! J.Ja

HavaCigar
HavaCigar

Once the configuration setting is read (and decrypted) it should be stored in as a SecureString.