Tyson Nero
Tyson Nero

Reputation: 2078

Unrecognized attribute 'configProtectionProvider' after encrypting app.config

I run the following method at the beginning of my application passing in a section living under applicationSettings:

public static void EncryptConfigSection(string sectionKey)
    {
        Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        ConfigurationSection section = config.GetSection(sectionKey);
        if (section != null)
        {
            if (!section.SectionInformation.IsProtected)
            {
                if (!section.ElementInformation.IsLocked)
                {
                    section.SectionInformation.ProtectSection("RSAProtectedConfigurationProvider");
                    section.SectionInformation.ForceSave = true;
                    config.Save(ConfigurationSaveMode.Full);
                    ConfigurationManager.RefreshSection(sectionKey);
                }
            }
        }
    }

Here's an example of the section in the app.config:

<applicationSettings>
  <Example.Properties.Settings>
    <setting name="Key" serializeAs="String">
      <value>Value</value>
    </setting>
  </Example.Properties.Settings>
</applicationSettings>

When I try to access any of the settings from the section, I receive the following error:

Unrecognized attribute 'configProtectionProvider'

This is a desktop application that needs to encrypt some settings when starting then decrypt when exiting.

Does anyone have a solution for this issue?

Upvotes: 11

Views: 11800

Answers (5)

rick schott
rick schott

Reputation: 21117

According to this blog post, the fix is to call RefreshSection() on the parent:

RefreshSection("applicationSettings")

Unrecognized attribute configProtectionProvider

Upvotes: 3

Terence Ang
Terence Ang

Reputation: 1

This post just saved my day and just in case someone need a fix in vb and 2017

    Private Sub ResetConfigMechanism()
        GetType(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, 0)
        GetType(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, Nothing)
        GetType(ConfigurationManager).Assembly.GetTypes().Where(Function(x) x.FullName = "System.Configuration.ClientConfigPaths").First().GetField("s_current", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, Nothing)
    End Sub

Upvotes: 0

Adiono
Adiono

Reputation: 1044

I found this: http://andybrennan.wordpress.com/2014/06/05/unrecognized-attribute-configprotectionprovider-after-encrypting-app-config/. And it's solves the problem.

Just use this method as written on the blog:

private void ResetConfigMechanism()
{
    typeof(ConfigurationManager)
        .GetField("s_initState", BindingFlags.NonPublic |
                                 BindingFlags.Static)
        .SetValue(null, 0);

    typeof(ConfigurationManager)
        .GetField("s_configSystem", BindingFlags.NonPublic |
                                    BindingFlags.Static)
        .SetValue(null, null);

    typeof(ConfigurationManager)
        .Assembly.GetTypes()
        .Where(x => x.FullName ==
                    "System.Configuration.ClientConfigPaths")
        .First()
        .GetField("s_current", BindingFlags.NonPublic |
                               BindingFlags.Static)
        .SetValue(null, null);
}

Invoke it after save/refresh the config.

Upvotes: 10

RB.
RB.

Reputation: 37192

I managed to get Rick Schott's answer working, with one important caveat - you cannot use the static version of ConfigurationManager.GetSection to retrieve the section after the refresh - you have to use Configuration.GetSection instead.

Full code:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection section = config.GetSection("passwordSection") as ConfigurationSection;

if (!section.SectionInformation.IsProtected)
{
    // Encrypt the section.
    section.SectionInformation.ProtectSection("DPAPIProtection");
    section.SectionInformation.ForceSave = true;
    config.Save(ConfigurationSaveMode.Modified);

    // The passwords are now encrypted.
    // Refresh the *parent* of the section that your passwords are in.
    ConfigurationManager.RefreshSection("configuration");

    // Now use Configuration.GetManager to retrieve the new password section.
    // This doesn't throw the Configuration Exception :)
    ConfigurationSection section2 = config.GetSection("passwordSection") as ConfigurationSection;
}

Upvotes: 5

Tyson Nero
Tyson Nero

Reputation: 2078

I was not able to encrypt/decrypt the config file while the application was running and continue to read the values.

Although not what I wanted, the solution to the problem was to first encrypt/decrypt the .config before the application ran.

Here is another approach which I didn't do but seemed interesting: Encrypting Passwords in a .NET app.config File

Upvotes: 2

Related Questions