Encrypting your web.config
Ever wanted to protect certain sections of your web.config?
In .net 2.0 we're provided with a few standard protection providers, and the ability
to write our own.
RSAProtectedConfigurationProvider : Default provider that uses RSA public
key encryption to encrypt/decrypt sections.
DPAPIProtectedConfigurationProvider : Provider that uses the Windows Data
Protection API (DPAPI) to encrypt/decrypt sections.
These providers can be invoked using a command-line tool, called aspnet_regiis (if
you've got full access to your webserver). You will notice two commands, the first
one calling the -pa attribute, this is your asp.net application identity, it gives
your web application rights to the configuration store.
If you're unsure about which account you're application is using, you can always output the
WindowsIdentity.GetCurrent().Name property somewhere, or simply check it out in IIS.
The second command using the -pe attribute does the actual encryption.
aspnet_regiis -pa "NetFrameworkConfigurationKey" "NT Authority\Network Service"
aspnet_regiis -pe "connectionStrings" -app "/WebApplication"
Or this can be done by writing a few simple lines of code (usually needed in a shared
hosting environment, where you've got certain restrictions)
In the code sample you'll find below you simply need to pass the name of the section
you wish to encrypt/decrypt, eg appSettings, connectionStrings
Note that not all sections can be encrypted in this manner, some examples are
<processModel>, <runtime>, <mscorlib>, <startup>, <system.runtime.remoting>,
<protectedData>, <satelliteassemblies>, <cryptographySettings>,
<cryptoNameMapping>, and <cryptoClasses>
Generally you would want to encrypt as little of the sections as possible (only
ones containing sensitive settings), since there is some performance overhead (.net
decrypts keys automatically in memory when needed, so that you dont need to decrypt
a section whenever you need to use it in your application).
C#
// Namespaces you'll need
using System.Configuration;
using System.Web.Configuration;
private void EncryptSection(string sectionName)
{
Configuration Config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
SectionInformation Section = Config.GetSection(sectionName).SectionInformation;
if (!Section.IsProtected)
{
Section.ProtectSection("RsaProtectedConfigurationProvider");
Section.ForceSave = true;
Config.Save(ConfigurationSaveMode.Modified);
}
}
private void DecryptSection(string sectionName)
{
Configuration Config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
SectionInformation Section = Config.GetSection(sectionName).SectionInformation;
if (Section.IsProtected)
{
Section.UnprotectSection();
Section.ForceSave = true;
Config.Save(ConfigurationSaveMode.Modified);
}
}
VB.net
'Namespaces you'll need
Imports System.Web.Configuration
Private Sub EncryptSection(ByVal sectionName As String)
Dim Config As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
Dim Section As SectionInformation = Config.GetSection(sectionName).SectionInformation
If Not Section.IsProtected Then
Section.ProtectSection("RsaProtectedConfigurationProvider")
Section.ForceSave = True
Config.Save(ConfigurationSaveMode.Modified)
End If
End Sub
Private Sub DecryptSection(ByVal sectionName As String)
Dim Config As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
Dim Section As SectionInformation = Config.GetSection(sectionName).SectionInformation
If Section.IsProtected Then
Section.UnprotectSection()
Section.ForceSave = True
Config.Save(ConfigurationSaveMode.Modified)
End If
End Sub
If everything worked out as planned, you'll end up with something similar to this in your
web.config.
<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>GCe06wmlf/snuz4o7cyNpTJ+z8gBXSv89De8GkcWlNSiFzRFryxM83gUzJJzs/ADotejMnnp0IukSdXKiFzelsBmShm7mi/E8RhSZa4Pb3NXFhqHxHnP3tASMeV98dJfKTSwC3Ct1/zRYqUBN3XR3ndnYLYvcbqtBPdM+Kl/0yY=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>nl7/3WpzEN/wHZgJwW35IQsWJjdvrkzvdO94MoPn/HK8LA94zV8yyYjJevvC+x6t5U4YOAqmSfc0pGA/FqPlbpYiuqjQ/HYMT3lRNAaHOk0=</CipherValue>
</CipherData>
</EncryptedData>
</appSettings>
Things can get a little bit more complicated once you find yourself in a webfarm for example,
where you'd need to export your RSA keys (since the actual key used for decrypting the ciphers gets stored on
the server) and deploy it to your farms etc - or perhaps rather simply do it programatically, using code
similar to which is provided in this blog.
Posted by - Christoff Truter
Date - 2008-06-18 07:42:23
Post comment