How to Encrypt Data Inside a web.config

Several weeks ago I was offered an opportunity to write articles for Arvixe. This is not only an exciting offer because of the vast number of people that will read it, but also because Arvixe is a great company. Their support has been impeccable and their desire to help has far exceeded my thoughts. (This is not because my thoughts are low).

My goal in writing articles is to provide an avenue that other developers can come to experience Arvixe in the way I am. Most of my how to articles will be around the Arvixe asp.net platform but most can be adjusted to accommodate other hosting providers. The great thing about development is that there are many ways to accomplish the same task.

Someone once asked me this question, “David, what is the best way to implement {fill in the blank}”. To which my response was, “Yes”. As you read my articles if you have a different way than just drop me a note. After all this is how we learn. So here goes the first one……

Before we get to the specific example, let me say, that Googling, Yahooing, Binging (is that a word?) will return many options so this not the only one, it is the one that I find is the most versatile. It can be used for many things.

  • Database connection strings.
  • Active Directory Administrator account
  • Secure api keys
  • Lock-down third party web service logins and password
  • A multitude of other options.

Furthermore; suppose you only want to lock down a particular line under app settings. You don’t want to decrypt and encrypt every time you want to change a default date, variable or other application settings. This solution might work for you. I am going to provide the steps necessary to pick and choose the variable, key or other paired value in the web.config to encrypt.

<configSections>
    <section name="MyAppSettings" type="System.Configuration.NameValueFileSectionHandler" />
	<!--...Other items for this section...-->
</configSections>

Then create a new section under the app settings tag like so.

  </appSettings>

  <MyAppSettings>
      <add key="VariableID" value="Arvixe1" />
  </MyAppSettings>

NOTE: Make sure that the name in the configSections matches the name in the brackets. In this case it is ‘MyAppSettings’

Then you need to add the following to the module / class / other service. This is what actually encrypts the section

    Private Sub EncryptConfigSection(sectionKey As String)
        'If it is a web app
		Dim config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~")
        'If it is a console app
		'Dim config As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)

		Dim section As ConfigurationSection = config.GetSection(sectionKey)
        If section IsNot Nothing Then
            If Not section.SectionInformation.IsProtected Then

                If Not section.ElementInformation.IsLocked Then
                    section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
                    section.SectionInformation.ForceSave = True
                    config.Save(ConfigurationSaveMode.Full)
                End If
            End If
        End If
    End Sub

Then on the application start or somewhere you need to call this sub.
Notice: The difference between a web app and a console app (exe).

  EncryptConfigSection("MyAppSettings")

You’re Done… The section of the web.config is encrypted. Now if you want to change the section just open up the web.config and delete the custom section (in this case MyAppsettings) and replace it with the decrypted changes. Rerun the application and it will encrypt it again.

The final step is to actually read the encrypted value (What good is encrypting if you can’t read it). Let’s place the code in for that.

Create a new module / class and add the following;

Imports System.Configuration

Namespace CustomConfigApp
    Public Class ConfigHelper
        Inherits ConfigurationSection
        ''' <summary>
        ''' The value of the property here "Folders"
        ''' needs to match that of the config file section
        ''' </summary>
        <ConfigurationProperty("FilterKeys")> _
        Public ReadOnly Property HashKeys() As FilterHashKeyCollection
            Get
                Return DirectCast(MyBase.Item("FilterKeys"), FilterHashKeyCollection)
            End Get
        End Property
    End Class

    ''' <summary>
    ''' The collection class that will store the list of each element/item that
    ''' is returned back from the configuration manager.
    ''' </summary>
    <ConfigurationCollection(GetType(FilterHashElement))> _
    Public Class FilterHashKeyCollection
        Inherits ConfigurationElementCollection
        Protected Overrides Function CreateNewElement() As ConfigurationElement
            Return New FilterHashElement()
        End Function

        Protected Overrides Function GetElementKey(element As ConfigurationElement) As Object
            Return DirectCast(element, FilterHashElement).Key
        End Function

        Default Public Overloads ReadOnly Property Item(idx As Integer) As FilterHashElement
            Get
                Return DirectCast(BaseGet(idx), FilterHashElement)
            End Get
        End Property
    End Class

    ''' <summary>
    ''' The class that holds onto each element returned by the configuration manager.
    ''' </summary>
    Public Class FilterHashElement
        Inherits ConfigurationElement
        <ConfigurationProperty("key", DefaultValue:="", IsKey:=True, IsRequired:=True)> _
        Public Property Key() As String
            Get
                Return DirectCast(MyBase.Item("key"), String)
            End Get
            Set(value As String)
                MyBase.Item("key") = value
            End Set
        End Property

        <ConfigurationProperty("value", DefaultValue:="", IsKey:=False, IsRequired:=False)> _
        Public Property Value() As String
            Get
                Return DirectCast(MyBase.Item("value"), String)
            End Get
            Set(value As String)
                MyBase.Item("value") = value
            End Set
        End Property
    End Class
End Namespace

This was originally put together by Brij M. on codeproject

Then when you want to use the value stored then use it like this.

        Dim section = TryCast(ConfigurationManager.GetSection("MyAppSettings"), NameValueCollection)
MyNewVariable = section("VariableID")

The great thing about this is that the decryption is already handled by asp.net.

Now you shouldn’t be afraid to encrypt sensitive data but use it when it makes sense.

I hope you enjoyed this article. You can download the project file here.

Looking for quality web hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , | Posted under ASP .NET 3.5, Programming/Coding | RSS 2.0

Author Spotlight

David Bauernschmidt

David Bauernschmidt

I live in the historical triangle of Virginia where I am married with two daughters. I have spent over 13 years working for a Fortune 500 company in the computer area. I started in VB 6.0 and by the time I ended my employment I was supervising a development team where we built many web applications. When my first daughter was born I wanted to spend more time with her so I left and became a programmer analyst for local government as well as launch my own company. Since then I have grown James River Webs into a profitable web design and application company helping small businesses create a big presence on the internet. As an employee I have created web application used by citizens and other companies. I enjoy fly fishing, and spending time with my family. I also enjoy learning new approaches and development tools when it comes to developing applications.

Leave a Reply

Your email address will not be published. Required fields are marked *


9 − 2 =

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>