Share via


Windows: Securing config sections using a ProtectedConfigurationProvider

the first option to use the feature without customization, you should add the configProtectedData section and add a new provider of type System.Configuration.DpApiProtectedConfigurationProvider : 

<configProtectedData>
    <providers>
      <add useMachineProtection="true" name="DPAPIProtection" type="System.Configuration.DpapiProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"/>
    </providers>
</configProtectedData>

and use it on your app startup : 

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

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

or you can override the encryption and decryption methods to have more control on the processes, and by so using your proper encryption algorithm, or package, i used a simple instance of DpApiProtectedConfigurationProvider just as example : 

// first you should inherit the ProtectedConfigurationProvider class 
public class ConfigurationSectionProvider: ProtectedConfigurationProvider 
{
    private string _sectionName;
    ProtectedConfigurationProvider _provider;
    public ConfigurationSectionProtector()
    {
        _provider = new DpapiProtectedConfigurationProvider();
    }

    public ConfigurationSectionProtector(string section)
    {
        _sectionName = section;
    }

    public ConfigurationSectionProtector(string sectionName, DpapiProtectedConfigurationProvider provider) : this(sectionName)
    {
        _provider = provider;
    }
    // here you can customize the decryption
    public override XmlNode Decrypt(XmlNode encryptedNode)
    {
        return _provider.Decrypt(encryptedNode);
    }
    // here you can customize the encryption
    public override XmlNode Encrypt(XmlNode node)
    {
        return _provider.Encrypt(node);
    }
}

and in your config file you should you should add it to the providers node of configProtectData section in your App.config : 

<configProtectedData>
    <providers>
      <add useMachineProtection="true" name="CustomDataProtectionProvider" type="{yournamespace}.ConfigurationSectionProtector,{yourAssemblyName}"/>
    </providers>
</configProtectedData>

<-- in the type value you should use 
use your namespace an your assembly name --!>

and the final step is the startup of your application you encrypt if not already encrypted: 

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

if (!section.SectionInformation.IsProtected)
{
    section.SectionInformation.ProtectSection(
        "CustomDataProtectionProvider");
}
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Modified);

this will concern the YourApp.exe.config file here is the result :

<connectionStrings configProtectionProvider="CustomDataProtectionProvider">
    <EncryptedData>
        <CipherData>
            <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAP/vYDfBwpEiV8jkazV9zhgQAAAACAAAAAAAQZgAAAAEAACAAAABb7t04YXbb8zPClpdLejVVuMOqtuqJtENwfB1o/jtXRgAAAAAOgAAAAAIAACAAAADDyx/NVUPtgeTjfT+/1UtrPYh+R6qryzyBAkwq+C+rf4ABAAAufQENm2NV3Y3t9v0/gMFam+KWFfMdt3U44a0Z2xeEt8F4pUtCAYGQV9ZDS+9XkGZ5/D3z5Ixn+4SMxqG1dNQ6dKifv+62/HsAZ2BeV2v9g5Gtahp9ww11QdAKZkNeGQlRnerIifT5wxgBksXFWcYyhDSMSiXhhQ0b1BGqQQUF2jj3euIAhX4DlZsk5D2QAeqWK01IL/rDES+oWFFgtbUU+KlCgBkpycE1ctU09+caduBojasC50DfeEWWX4kitY47CvSHJ5GWLhO2Da+oCaBxSwKr83DCGGHkwcWQocDuKypU7sks3RjCVkiYbcu9mwk3m8dXLleVWtkiz7F4jv9z3YPWwq3+8XP98/lgR2wDC3F6gEjN+nsJuFrWwBSnQPtk0MiwV0htQIaQghrG8EOAcckBWY3TKyouqZtLH68zczbcU72vQUwY485eco1Inher9WQhVejQ1HjpzFy+pvDGObBTX1AOd2aIPzCx23HHrxJFeDJ6Tb0hjTKaMSHg8LdAAAAAARc58hXAn3DxnoOaH9CNWv6u5hyWJG7HwYvLv0/5FIzlSqwaJX2MsrlPumVTpghSnV6axX3YJbV6qQ27l0zNpg==</CipherValue>
        </CipherData>
    </EncryptedData>
</connectionStrings>

See more: Implementing Protected Configuration With Windows