ASP.Net offers the possibility to encrypt sections in the web.config automatically. It seems 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.
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 operation are performed on sections and not on the file as a whole.
Developers can extent 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.
2 <configuration>
3 <configSections>
4 <section name="Vault" type="System.Configuration.NameValueSectionHandler" />
5 <sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" >
6 <section name="EncryptConnStringsSection.My.MySettings"
type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
7 </sectionGroup>
8 </configSections>
9 <connectionStrings>
10 <add name="EncryptConnStringsSection.My.MySettings.testConn"
11 connectionString="Data Source=kissvr07;Initial Catalog=ProjectX_Dev;Integrated Security=True" />
12 </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 transperant 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 the are two encryption algorithms supported via providers: DPAPIProtectedConfigurationProvider and 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.
1 Imports System.Configuration
2
3 ''' <summary>
4 ''' This class protects (encrypts) a section in the applications configuration file.
5 ''' </summary>
6 ''' <remarks>The <seealso cref="RsaProtectedConfigurationProvider" /> is used in this implementation.</remarks>
7 Public Class ConfigSectionProtector
8
9 Private m_Section As String
10
11 ''' <summary>
12 ''' Constructor.
13 ''' </summary>
14 ''' <param name="section">The section name.</param>
15 Public Sub New(ByVal section As String)
16 If String.IsNullOrEmpty(section) Then Throw New ArgumentNullException("ConfigurationSection")
17
18 m_Section = section
19 End Sub
20
21 ''' <summary>
22 ''' This method protects a section in the applications configuration file.
23 ''' </summary>
24 ''' <remarks>The <seealso cref="RsaProtectedConfigurationProvider" /> is used in this implementation.</remarks>
25 Public Sub ProtectSection()
26 ' Get the current configuration file.
27 Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
28 Dim protectedSection As ConfigurationSection = config.GetSection(m_Section)
29
30 ' Encrypts when possible
31 If ((protectedSection IsNot Nothing) _
32 AndAlso (Not protectedSection.IsReadOnly) _
33 AndAlso (Not protectedSection.SectionInformation.IsProtected) _
34 AndAlso (Not protectedSection.SectionInformation.IsLocked) _
35 AndAlso (protectedSection.SectionInformation.IsDeclared)) Then
36 ' Protect (encrypt)the section.
37 protectedSection.SectionInformation.ProtectSection(Nothing)
38 ' Save the encrypted section.
39 protectedSection.SectionInformation.ForceSave = True
40 config.Save(ConfigurationSaveMode.Full)
41 End If
42 End Sub
43 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.
Protecting connectionstrings
It is simpler to protected or unprotect connectionstrings. It can be done with the following code sample:
1 ' Connection string encryption
2 Dim config As Configuration = _
3 ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
4 config.ConnectionStrings.SectionInformation.ProtectSection(Nothing)
Updated: I published it on The Codeproject. It may be more update there. Check it out.