Introduction
Sensitive information should not be kept as clear text. At times, we need to store sensitive information into the web.config file. To protect the information, we can encrypt it.
How to protect
To protect the information mentioned in config files, we need to encrypt the config file sections. There are providers in ASP.NET 2.0 which can be used to encrypt the information in the web.config file. We can create our own providers to take care of the encryption/decryption mechanism.
In .NET 2.0, using a command line utility, we can encrypt the information in specific sections of the web.config file.
The following command can be used to encrypt the specific sections of the web.config:
aspnet_regiis -pef "SECTION_NAME" "PHYSICAL_DIR_PATH_OF_WEB_CONFIG"
-prov "PROVIDER"
To decrypt, you need to use the following command:
aspnet_regiis -pdf "SECTION_NAME" "PHYSICAL_DIR_PATH_OF_WEB_CONFIG"
Note: There are sections of the web.config file which cannot be encrypted.
The following piece of code can be used to have a custom provider for encryption/decryption of web.config sections.
Code for custom provider
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
public class MyProtectedConfigProvider : ProtectedConfigurationProvider
{
# region Declarations
private TripleDESCryptoServiceProvider _cryptoProvider =
new TripleDESCryptoServiceProvider();
private string _key;
private string _vector;
private string _name;
# endregion
# region Properties
public string Key
{
get { return _key; }
}
public string Vector
{
get { return _vector; }
}
public override string Name
{
get { return _name; }
}
# endregion
# region Overrides
public override void Initialize(string name, NameValueCollection config)
{
_name = name;
_key = config["key"];
_vector = config["vector"];
_cryptoProvider.Key = HexToByte(_key);
_cryptoProvider.IV = HexToByte(_vector);
}
public override XmlNode Encrypt(XmlNode node)
{
XmlDocument xmlDoc = new XmlDocument();
string encryptedData = EncryptString(node.OuterXml);
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml("<EncryptedData>" +
encryptedData +
"</EncryptedData>");
return xmlDoc.DocumentElement;
}
public override XmlNode Decrypt(XmlNode encryptedNode)
{
string decryptedData = DecryptString(encryptedNode.InnerText);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(decryptedData);
return xmlDoc.DocumentElement;
}
# endregion
# region Encryption/Decryption
private string EncryptString(string encryptValue)
{
byte[] valBytes = Encoding.Unicode.GetBytes(encryptValue);
ICryptoTransform transform = _cryptoProvider.CreateEncryptor();
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
cs.Write(valBytes, 0, valBytes.Length);
cs.FlushFinalBlock();
byte[] returnBytes = ms.ToArray();
cs.Close();
return Convert.ToBase64String(returnBytes);
}
private string DecryptString(string encryptedValue)
{
byte[] valBytes = Convert.FromBase64String(encryptedValue);
ICryptoTransform transform = _cryptoProvider.CreateDecryptor();
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
cs.Write(valBytes, 0, valBytes.Length);
cs.FlushFinalBlock();
byte[] returnBytes = ms.ToArray();
cs.Close();
return Encoding.Unicode.GetString(returnBytes);
}
# endregion
# region Supporting methods
private string ByteToHex(byte[] byteArray)
{
string outString = "";
foreach (Byte b in byteArray)
outString += b.ToString("X2");
return outString;
}
private byte[] HexToByte(string hexString)
{
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] =
Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
# endregion
}
You need to include the following in the web.config file under the configuration node:
<configProtectedData>
<providers>
<add name="MyProtectedProvider"
type="MyNamespace.MyProtectedConfigProvider,MyProtectedConfigProvider,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=4653ckjfie250a45e9"
key="################################################"
vector="################"
/>
</providers>
</configProtectedData>
Now using the command line utility and providing the name of this custom provider, we can encrypt/decrypt sections of the web.config file. The key and vector can be the same in the case of a web farm implementation, if required.
Note: This even encrypts the section which is physically in different files and referenced in the web.config file.
For example:
<appSettings configSource="configurations/appSettings.config"/>
This will go inside the appSettings
file and encrypt the section.
Conclusion
This piece of code can help create your own cryptography provider to encrypt/decrypt the sections in web.config. This might be useful when you have to encrypt the sections of web.config in a Web Farm scenario. This is also helpful for using your own cryptography mechanism.