Introduction
ASP.NET offers the possibility to encrypt sections in the web.config automatically. It seems it is not possible for WinForm applications to do that for the app.config. And this is true for a part: WinForms does not offer tools to configure it. But it can be done. It is all .NET. Isn't it? So how do we do it? Read on and see how.
Using the Code
First let me explain something about the configuration files in .NET. The app.config and web.config are divided into sections. The encrypting and decrypting operations are performed on sections and not on the file as a whole.
Developers can extend a configuration file by defining custom sections. This can be done by adding a section tag to the configSections
element or the sectionGroup
element like in the example below. The name
attribute of section element specifies the name of the new section. The type
attribute specifies the handler that processes the configuration
section: it gets the data out of the section. As you can see in the example below, I implemented both scenarios.
="1.0"="utf-8"
<configuration>
<configSections>
<section name="Vault"
type="System.Configuration.NameValueSectionHandler" />
<sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="EncryptConnStringsSection.My.MySettings"
type="System.Configuration.ClientSettingsSection, System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</sectionGroup>
</configSections>
<connectionStrings>
<add name="EncryptConnStringsSection.My.MySettings.testConn"
connectionString="Data Source=someserver;Initial
Catalog=ProjectX_Dev;Integrated Security=True" />
</connectionStrings>
Now that I have explained how to create sections in the app.config, let's go on to show how to encrypt a section. It is really a simple operation. And once a section has been encrypted, you do not have to worry about decrypting it. The .NET Framework does it automatically for you. It is a transparent operation and works as if you did not encrypt the section.
The configuration
namespace contains a class that represents a section. This class is called ConfigurationSection
. A member of this class is the ElementInformation
property. This property gets information about a section and it has the method ProtectSection
defined on it. This method encrypts the section. Out of the box, there are two encryption algorithms supported via providers:
DPAPIProtectedConfigurationProvider
RSAProtectedConfigurationProvider
The default provider is RSAProtectedConfigurationProvider
. You use the default provider by passing nothing/null
as a parameter to the ProtectSection
method.
I wrote the following class to demonstrate this method:
Imports System.Configuration
Public Class ConfigSectionProtector
Private m_Section As String
Public Sub New(ByVal section As String)
If String.IsNullOrEmpty(section) Then _
Throw New ArgumentNullException("ConfigurationSection")
m_Section = section
End Sub
Public Sub ProtectSection()
Dim config As Configuration = ConfigurationManager.OpenExeConfiguration
(ConfigurationUserLevel.None)
Dim protectedSection As ConfigurationSection = config.GetSection(m_Section)
If ((protectedSection IsNot Nothing) _
AndAlso (Not protectedSection.IsReadOnly) _
AndAlso (Not protectedSection.SectionInformation.IsProtected) _
AndAlso (Not protectedSection.SectionInformation.IsLocked) _
AndAlso (protectedSection.SectionInformation.IsDeclared)) Then
protectedSection.SectionInformation.ProtectSection(Nothing)
protectedSection.SectionInformation.ForceSave = True
config.Save(ConfigurationSaveMode.Full)
End If
End Sub
End Class
As you can see, this class also has a method ProtectSection
. Basically it gets section information out of the app.config and checks if it can be encrypted. If so, it protects the section using the default encryption provider and it saves it. And it's done.
It is simpler to protect or unprotect connectionstrings
. It can be done with the following code sample:
Dim config As Configuration = ConfigurationManager.OpenExeConfiguration
(ConfigurationUserLevel.None)
config.ConnectionStrings.SectionInformation.ProtectSection(Nothing)
config.Save(ConfigurationSaveMode.Full, True)
History
- 30-03-2007: Initial version
- 12-04-2007: Added a link to my blog. Maybe you will like it. Let me know, please.
- 18-04-2007: Updated the example project
- 21-04-2007: Updated last code example