none
encrypting user settings RRS feed

  • Question

  • I am having trouble figuring out how to encrypt the user.config file stored in the application data directory. I can encrypt the app.config just fine. Is there a function or property that will either give me the exact directory of where the user.config is created or is there a function analogous to ConfigurationManager.OpenExeConfiguration but for the user settings instead?
    Thursday, May 10, 2007 8:53 PM

Answers

  • CoderD,

     

    Storing secrets (i.e. passwords) is actually a very difficult task, and depending on the requirements, the actual implementation will be very different. Having a one-size-fits-all approach is virtually impossible! The first choice should be not to store the password unless it is really necessary!

     

    If this secret is per user (that is, every user has his/her own password) you could consider either prompting the user (that way, the password doesn't have to be saved) or simply put the appropriate ACL on the user.config file to prevent other users from opening it.

    If the secret is application scoped (i.e. belongs to the application), you may want to consider encrypting the applicationSettings section(s) in your app.config file. Please note that this will *not* prevent users from reading the value - it will only be slightly more difficult - but since you explicitly stated that this is ok, I'm boing to take your word for it.

     

    If you dig around a bit for ProtectedConfigurationSection on MSDN, you'll find a bunch of information on how to encrypt a configuration file. Most of the docs are for ASP.NET (since that is where this is most useful), but the same applies to client applications as well...

     

    Just for fun, I whipped up a quick sample that you can compile and pass the name of a configuration file to to encrypt all the applicationSettings sections in the file (see below). Again, this is only an example - don't assume that this is a 100% secure solution! Also, you have to run this on the machine where you want your app to run - it uses a machine specific key to encrypt the configuration file...

     

    Code Snippet

    Option Strict On

    Option Explicit On

     

    Module Module1

     

        Sub Main()

            If System.Environment.GetCommandLineArgs().Length <> 2 Then

                Throw New ArgumentException("Pass in the configuration file you want to encrypt as the first argument")

            End If

     

            Dim configFileToModify As String = System.Environment.GetCommandLineArgs()(1)

            Dim map As New System.Configuration.ExeConfigurationFileMap()

            map.ExeConfigFilename = configFileToModify

     

            Dim cfg As System.Configuration.Configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(map, Configuration.ConfigurationUserLevel.None)

     

            ' If I want to use another provider, I can declare my own provider/provider settings

            ' and use it instead

            SampleDeclareProtectionProvider(cfg, "A sample provider")

            EncryptApplicationSettingsSections(cfg, "A sample provider")

     

            ' The DataProtectionConfigurationProvider is usually declared in your Machine.config file,

            ' so you don't need to configure it in the app.config file

            EncryptApplicationSettingsSections(cfg, "DataProtectionConfigurationProvider")

     

            cfg.Save()

        End Sub

     

        Public Sub SampleDeclareProtectionProvider(ByVal cfg As System.Configuration.Configuration, ByVal providerName As String)

            Dim cfgProtectedDataSection As System.Configuration.ProtectedConfigurationSection = TryCast( _

                    cfg.Sections("configProtectedData"), _

                System.Configuration.ProtectedConfigurationSection)

     

            Dim providerSettings As New System.Configuration.ProviderSettings(providerName, GetType(System.Configuration.DpapiProtectedConfigurationProvider).AssemblyQualifiedName)

            cfgProtectedDataSection.Providers.Add(providerSettings)

        End Sub

     

        Public Sub EncryptApplicationSettingsSections(ByVal cfg As System.Configuration.Configuration, ByVal providerName As String)

            Dim applicationSettingsSectionGroup As System.Configuration.ConfigurationSectionGroup = _

                        cfg.SectionGroups("applicationSettings")

            If applicationSettingsSectionGroup IsNot Nothing Then

                For Each section As System.Configuration.ConfigurationSection In applicationSettingsSectionGroup.Sections

                    section.SectionInformation.ProtectSection(providerName)

                Next

            End If

        End Sub

     

    End Module

     

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1059709&SiteId=1

    Wednesday, May 16, 2007 7:50 AM