Problem Statement: Its very common situation when we need to encrypt the confidential information like user credential present in configuration file. There are many ways from which we can encrypt the configuration section. We can use some encrypted text using some algorithms like SHA1 etc. But this involve the overhead of writing code for doing the job encryption and decryption. .NET provides some build in protection providers which will be discussed in further sections:
Solution: Protected Configuration Provider helps in encrypting the sections of configuration file in order to protect the sensitive information of the application. This will results in making the application difficult for attacker to fetch sensitive information. .NET framework provides two ways of protected configuration provider:
1. RSAProtectedConfigurationProvider: This uses RSACryptoServiceProviderto encrypt the configuration sections
2. DPAPIProtectedConfigurationProvider: This uses Windows Data Protection API (DPAPI) to encrypt configuration section
The coming section will show the way to decrypt the configuration file.
|
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="username" value="a2zmenu"/>
<add key="password" value="password"/>
</appSettings>
</configuration> |
The default section will look like as given above have username and password as plain text and now we want to decrypt the same.
|
static void Main(string[] args)
{
string userNameWithoutEncryption = ConfigurationManager.AppSettings["username"];
EncryptAppSettings("appSettings");
string userNameWithEncrytionApplied = ConfigurationManager.AppSettings["username"];
}
/// <summary>
/// This method is used to encrypt the particular section in the application config
/// </summary>
/// <param name="section">Section to encrypt</param>
private static void EncryptAppSettings(string section)
{
Configuration objConfig = ConfigurationManager.OpenExeConfiguration(GetAppPath() + "AppKeyEncryption.exe");
AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection(section);
if (!objAppsettings.SectionInformation.IsProtected)
{
objAppsettings.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
objAppsettings.SectionInformation.ForceSave = true;
objConfig.Save(ConfigurationSaveMode.Modified);
}
}
/// <summary>
/// This method is used to fetch the location of location of executable
/// </summary>
/// <returns>location of executable</returns>
private static string GetAppPath()
{
System.Reflection.Module[] modules = System.Reflection.Assembly.GetExecutingAssembly().GetModules();
string location = System.IO.Path.GetDirectoryName(modules[0].FullyQualifiedName);
if ((location != "") && (location[location.Length - 1] != '\\'))
location += '\\';
return location;
} |
The above code snippet will pick up the configuration file with the help of GetAppPath() and applies RsaProtectedConfigurationProvider to encrypt the particular section of the configuration file. The configuration file will look like as given below:
|
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="customAppSettings" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<appSettings configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>09+Lm23xDWWnAZFOagh3NRwp5tzad+3oedvTgoeWqunQBiAfk9UGfGxriZg6snwwANUDzOANZ+wOFUb6qa0Atf
NgSd6b4FFSKTqzkfLlk+S9GtPSAVrRaLU9
/Q2Qu7oxoSbhW7NWtengJbEZrFm+GqlLlm08w8Np/y03DMExFeA=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>qSYRXNEKhbwNodH60c7qoWeKZ2QKVQmizPXVGCgHVZPMQ4F+XDqlZa2OyIin0kEI3j8pCjNL097RlZClgdd
gPEd61AEw6DXJc43Z98obNFHmXfK9aS67qEtO6E
T+qCWQq2ZRbfK6xZ6jlfeink35/veUmoxAmDXrkwdrbQVKv98=</CipherValue>
</CipherData>
</EncryptedData>
</appSettings>
</configuration> |
After calling EncryptAppSettings method the configuration file will be encrypted now and we can access the keys in the same way as we do earlier. The configuration provider will take care of fetching the values.
The above snapshot is before configuration file encrypted.
The above snapshot is after EncryptAppSettings is called and configuration file is encrypted. The way of accessing the key will remain the same J.
|
/// <summary>
/// This method is used to decrypt the particular section of the application config
/// </summary>
/// <param name="section">Section to encrypt</param>
private static void DecryptAppSettings(string section)
{
Configuration objConfig = ConfigurationManager.OpenExeConfiguration(GetAppPath() + "AppKeyEncryption.exe");
AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection(section);
if (objAppsettings.SectionInformation.IsProtected)
{
objAppsettings.SectionInformation.UnprotectSection();
objAppsettings.SectionInformation.ForceSave = true;
objConfig.Save(ConfigurationSaveMode.Modified);
}
} |
The above method will decrypt configuration file to the original one.
Note: The RsaProtectedConfigurationProviderwill decrypt the configuration file with the help of keys generated on the machine so if encrypted configuration file cannot be used on different machine.
In the above sections describe the way of encrypting configuration file to protect the sensitive information like password. Now what if we want to change the key value say password after sometime as our configuration file is encrypted we cannot update the password easily. No worries .NET framework provide the way to do so as given below:
|
/// <summary>
/// This method is used to update the key value
/// </summary>
/// <param name="newValue">New value of the key</param>
private static void UpdateKey(string newValue)
{
ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename = ConfigurationManager.AppSettings["configPath"];
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
config.AppSettings.Settings["password"].Value = newValue;
config.Save();
} |
Here we conclude the way of encypting the configuration file.
Happy Coding J