45

ASP.NET 4

I've used RSA key encryption for connection strings in web.config on my web farm. However, there's one more custom password entry that I'd like to encrypt. How should I encrypt it with RSA key without having the rest configurations being encrypted. Please advise, thanks.

Example:

  <appSettings>
        ...
    <add key="Host" value="www.foo.com" />
    <add key="Token" value="qwerqwre" />
    <add key="AccountId" value="123" />
    <add key="DepartmentId" value="456" />
    <add key="Password" value="asdfasdf" />
    <add key="SessionEmail" value="foo@foo.com" />
    <add key="DefaultFolder" value="789" />
  </appSettings>
Stan
  • 37,207
  • 50
  • 124
  • 185

3 Answers3

64

You could put the password into a separate section and encrypt this section only. For example:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="secureAppSettings" type="System.Configuration.NameValueSectionHandler, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </configSections>

    <appSettings>
        <add key="Host" value="www.foo.com" />
        <add key="Token" value="qwerqwre" />
        <add key="AccountId" value="123" />
        <add key="DepartmentId" value="456" />
        <add key="SessionEmail" value="foo@foo.com" />
        <add key="DefaultFolder" value="789" />  
    </appSettings>

    <secureAppSettings>
        <add key="Password" value="asdfasdf" />
    </secureAppSettings>  
</configuration>

and then (note that I am using DPAPI in my example so adapt the provider for RSA):

aspnet_regiis -pef secureAppSettings . -prov DataProtectionConfigurationProvider

Once encrypted the file will look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="secureAppSettings" type="System.Configuration.NameValueSectionHandler, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </configSections>

    <appSettings>
        <add key="Host" value="www.foo.com" />
        <add key="Token" value="qwerqwre" />
        <add key="AccountId" value="123" />
        <add key="DepartmentId" value="456" />
        <add key="SessionEmail" value="foo@foo.com" />
        <add key="DefaultFolder" value="789" />  
    </appSettings>

    <secureAppSettings configProtectionProvider="DataProtectionConfigurationProvider">
        <EncryptedData>
            <CipherData>
                <CipherValue>AQAAANCMnd.......</CipherValue>
            </CipherData>
        </EncryptedData>
    </secureAppSettings>  
</configuration>

The way you would access those settings in your application once the file is encrypted is still the same and completely transparent:

var host = ConfigurationManager.AppSettings["Host"];
var password = ConfigurationManager.AppSettings["Password"];
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    How come it's not ConfigurationManager.secureAppSettings["Password"]? What makes .NET can treat that secureAppSettings section as part of appSettings? – Stan Jun 03 '11 at 09:32
  • 3
    @Stan, it uses a `NameValueSectionHandler`. – Darin Dimitrov Jun 03 '11 at 09:36
  • 2
    I am not able to retrieve the value of "Password" in from "secureAppSettings" section using "ConfigurationManager.AppSettings["Password"];" in .net 3.5 asp.net website. – nRk Dec 26 '11 at 16:32
  • 12
    Try using the following: var section = ConfigurationManager.GetSection("secureAppSettings") as NameValueCollection; var configPwd = section["LoginPassword"]; – okenshield Mar 13 '12 at 09:22
  • 1
    This almost worked for me. I had to use a different type in the configSections section tag:
    – iandisme Apr 11 '17 at 19:52
  • This type worked for me too. In the code, I just call it a NameValueCollection var section = (NameValueCollection)ConfigurationManager.GetSection("secureAppSettings"); var s = section[key]; – Allen May 09 '19 at 19:25
14

In c# and .Net 4.5 I had to use this to read the encrypted setting:

string password = ((System.Collections.Specialized.NameValueCollection)ConfigurationManager.GetSection("secureAppSettings"))["Password"];

but otherwise works a treat.

Moe Howard
  • 498
  • 7
  • 12
user2993145
  • 149
  • 1
  • 5
8

You can't encrypt a single entry - the infrastructure only allows for encryption of whole config sections.

One option is to place the entry in its own config section and encrypt that.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • Do you know if it is possible to encrypt a subsection? http://stackoverflow.com/questions/34504301/encrypt-a-subsection-of-web-config – TTT Jul 27 '16 at 15:32
  • This is not true: https://blogs.msdn.microsoft.com/gaurav/2013/12/15/encrypting-section-of-config-file-using-aspnet_regiis-exe-the-configuration-for-physical-path-web-config-cannot-be-opened/ – Ryan Mendoza Aug 02 '16 at 15:49
  • 1
    @RyanMendoza - you need to read that article again. A single **node**, or single **entry** cannot be encrypted - the whole section needs to be encrypted. – Oded Aug 02 '16 at 15:50
  • @Allen - guess I'll have to disagree. The above answer shows how to move an entry to a section and then encrypt that section... which is basically my second sentence. – Oded May 10 '19 at 13:01