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>