4
votes

Note that I am aware of this question:
Encrypting AppSettings in file external to Web.Config

And this is NOT a dupe. That question has an answer allowing the encryption of an external appSettings config file only if appSettings is linked using the configSource attribute. I want to use the file attribute. So, I have something like this in my Web.config:

<appSettings file="ExternalSettings.config">
    <add key="InternalSetting" value="Test123" />
</appSettings>

... and an ExternalSettings.config file in the same directory with its own appSettings section. When I run my web app, the two appSettings contents are merged together. However, if I try to just encrypt my ExternalSettings.config file like this:

var webConfig = WebConfigurationManager.OpenWebConfiguration("~/ExternalSettings.config");
ConfigurationSection section = webConfig.GetSection("appSettings");
if (!section.SectionInformation.IsProtected) {
    section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
    webConfig.Save();
}

I get a ConfigurationErrorsException saying

"A configuration file cannot be created for the requested Configuration object."

(by the way, this code works fine for encrypting an appSettings section that is just in Web.config)

Is there any way of encrypting the settings in my ExternalSettings.config file, but leaving the Web.Config ones unencrypted?

2

2 Answers

2
votes

Yes this is possible. You can use the following code to encrypt the appSettings of a configuration file.

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "ExternalSettings.config";
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
AppSettingsSection section = configuration.AppSettings;
if (section != null && section.SectionInformation.IsProtected == false)
{
    section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
    configuration.Save();
}

However, this expects a valid configuration file and not an appSettings snippet. So you need to enclose the appSettings in a configuation element before running

<configuration>
    <appSettings>
        <add....
    </appSettings>
</configuration>

This will turn the file into something like

<configuration>
  <appSettings configProtectionProvider="DataProtectionConfigurationProvider">
    <EncryptedData>
      <CipherData>        <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAADx8S4qABcUakeKay9R2hvgQAAAACAAAAAAADZgAAwAAAABAAAAAyNc22wc25O41jcxXcAD8MAAAAAASAAACgAAAAEAAAAIRVbMW6KjGTFu0O8ZC1YGqIAAAAO6L8wKbLrXX4WSh+HBMPMzR1ypiWMGfC/tFS0swDwYCbBYZEXM1WU9vf3XTA/zftK+6yYLDXQ348Easx0f/a+IaZlsUvtsCJ9LSBSVM/++7JZkKrq2Zah2aQjqjn3G80XqCNc+OCNiFRhmb2ng8m3ioxC/CeOC9mVBX2qz97PIend+u4CLVBIhQAAAAsoiPgaQd9sRcFjsXQuYtTWY+qgw==</CipherValue>
      </CipherData>
    </EncryptedData>
  </appSettings>
</configuration>

Then remove the configuration start and end elements once encrypted and the runtime will pick up the values as before when unencrypted.

0
votes

I think that your problem is related to mixing keys from main and external configurations. The following definition works fine for me:

<appSettings file="Configuration\AppSettings.config" />

Something in external file

<appSettings>
    <!--Your configuration keys-->
</appSettings>

External section correctly encrypt/decrypt