26

Is there a utility that will encrypt a named configuration section (or just the connectionStrings section) in an app.config file in a similar manner that one can use aspnet_regiis with web.config files?

I know this can be done in code - there are code examples out there, but I am hoping to avoid writing an application for this.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • Oded, curious to know the specific motivation for this? – wal Apr 27 '11 at 11:59
  • 1
    @wal - Urgent business requirement to encrypt all connection string sections. Easily done on `web.config` files using `aspnet_regiis`, not so easy with `app.config`. – Oded Apr 27 '11 at 12:14
  • If its urgent/quick then I can only suggest to encrypt the entire file by ticking 'Encrypt contents to secure data' under file -> Properties Advanced. :| – wal Apr 27 '11 at 12:50
  • also will probably be more of a pain in practice depending on which user IIS runs under. still, may make management happy. – wal Apr 27 '11 at 12:53

4 Answers4

18

You can try the following:

https://magenic.com/thinking/encrypting-configuration-sections-in-net

In short - rename the app.config file to web.config - the schema is identical, so aspnet_regiis works. Rename back to app.config when finished.

JD Brennan
  • 992
  • 1
  • 10
  • 20
RBZ
  • 2,034
  • 17
  • 34
  • -1 - This just creates a `web.config` file with an encrypted section, which when decrypted is empty. It doesn't even look at the `app.config` file. – Oded Apr 27 '11 at 12:35
  • It was the first thing I tried. Doesn't make a whit of difference. Test before you post. – Oded Apr 27 '11 at 12:40
  • Seems to work pretty well for me and has in several environment. run this command from your root web folder. where you web.config is located. Best of luck – RBZ Apr 27 '11 at 12:43
  • I suggest you read my question. I am not asking about `web.config`, I am asking about **`app.config`**. No "root web folder" to be seen. – Oded Apr 27 '11 at 12:44
  • 1
    try this then http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx – RBZ Apr 27 '11 at 12:50
  • OK, that works. Can you please edit your answer to better reflect my question (and add the detail in the blog post you linked in your comment). I will not be able to undo my downvote until your answer is edited. – Oded Apr 27 '11 at 13:29
  • 8
    One thing I do not get is how is the key distributed? I mean the client machine will have to way to decrypt the configurationStrings section. It works on my developer machine, but I imagine regiis tool saved the key somewhere. – One-One Jan 31 '14 at 07:28
  • The key container is distributed by exporting to an XML file, copying to the target machine, and importing. This is facilitated through the aspnet_regiis tool and is documented well. – atjoedonahue Mar 24 '22 at 15:48
9

Old question, but here is the Microsoft way:

.NET 2.0: http://msdn.microsoft.com/en-us/library/89211k9b(v=vs.80).aspx

.NET 3.5: http://msdn.microsoft.com/en-us/library/ms254494(v=vs.90).aspx (Section "Encrypting Configuration File Sections Using Protected Configuration")

Toggle Encryption on app.config file:

static void ToggleConfigEncryption(string exeConfigName)
{
    // Takes the executable file name without the 
    // .config extension. 
    try
    {
        // Open the configuration file and retrieve  
        // the connectionStrings section.
        Configuration config = ConfigurationManager.
            OpenExeConfiguration(exeConfigName);

        ConnectionStringsSection section =
            config.GetSection("connectionStrings")
            as ConnectionStringsSection;

        if (section.SectionInformation.IsProtected)
        {
            // Remove encryption.
            section.SectionInformation.UnprotectSection();
        }
        else
        {
            // Encrypt the section.
            section.SectionInformation.ProtectSection(
                "DataProtectionConfigurationProvider");
        }
        // Save the current configuration.
        config.Save();

        Console.WriteLine("Protected={0}",
            section.SectionInformation.IsProtected);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}
MichelZ
  • 4,214
  • 5
  • 30
  • 35
5

Compile this console application, and drag a config file onto it. It will spit out a copy of the config file with its connection strings encrypted.

Note that you must encrypt as the same user who will consume the config file.

using System;
using System.Configuration;
using System.IO;

namespace ConnectionStringEncryptor
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                throw new ArgumentException("Please supply a config file to encrypt");
            }
            string originalConfigFilePath = args[0];
            AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", originalConfigFilePath);
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
            connectionStringsSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
            config.SaveAs(originalConfigFilePath + ".encrypted");
        }
    }
}
Jay Sullivan
  • 17,332
  • 11
  • 62
  • 86
2

PowerShell implementation based on MichelZ's answer:

<#
.SYNOPSIS
Encrypts a section in .NET app configuration file.
#>
function Protect-DotNetConfigSection
{
    [CmdletBinding()]
    param
    (
        # Path to .exe file.
        [Parameter(Mandatory = $true)]
        [string] $ExePath,
        # List of section names.
        [Parameter(Mandatory = $true)]
        [string[]] $Sections
    )

    $config = [System.Configuration.ConfigurationManager]::OpenExeConfiguration($ExePath)

    foreach ($section in $Sections)
    {
        $config.GetSection($section).SectionInformation.ProtectSection('DataProtectionConfigurationProvider')
    }

    $config.Save()
}

Protect-DotNetConfigSection 'C:\MyApp\MyApp.exe' 'connectionStrings'
Protect-DotNetConfigSection 'C:\MyApp\MyApp.exe' @('connectionStrings', 'appSettings')
Der_Meister
  • 4,771
  • 2
  • 46
  • 53
  • Sweet 'n easy. Definitely qualifies as an answer to the OP, as copying & pasting your script into a text file isn't considered writing an application. – Dan Z Jul 04 '18 at 11:24