加密 web.config 文件节






2.63/5 (7投票s)
在 ASP.NET 2.0 中使用自定义提供程序加密 web.config 文件节。
引言
敏感信息不应以明文形式存储。有时,我们需要将敏感信息存储到 web.config 文件中。为了保护信息,我们可以对其进行加密。
如何保护
为了保护配置文件中的信息,我们需要加密配置文件节。ASP.NET 2.0 中有提供程序可用于加密 web.config 文件中的信息。我们可以创建自己的提供程序来处理加密/解密机制。
在 .NET 2.0 中,可以使用命令行实用程序加密 web.config 文件中特定节的信息。
以下命令可用于加密 web.config 的特定节
aspnet_regiis -pef "SECTION_NAME" "PHYSICAL_DIR_PATH_OF_WEB_CONFIG"
-prov "PROVIDER"
要解密,您需要使用以下命令
aspnet_regiis -pdf "SECTION_NAME" "PHYSICAL_DIR_PATH_OF_WEB_CONFIG"
注意:web.config 文件中有些节无法加密。
以下代码片段可用于拥有一个自定义提供程序,用于加密/解密 web.config 节。
自定义提供程序代码
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 RijndaelManaged _rijndaelManaged = new RijndaelManaged();
//Any other crypto provider can be used as required.
private string _key;
private string _vector;
private string _name;
# endregion
# region Properties
/// <summary>
/// Key for encryption/decryption
/// </summary>
public string Key
{
get { return _key; }
}
/// <summary>
/// Vector for encryption/decryption
/// </summary>
public string Vector
{
get { return _vector; }
}
/// <summary>
/// Name of the provider
/// </summary>
public override string Name
{
get { return _name; }
}
# endregion
# region Overrides
/// <summary>
/// Provider initialization
/// </summary>
/// <param name="name">name of the provider</param>
/// <param name="config">configuration parameters collection</param>
public override void Initialize(string name, NameValueCollection config)
{
_name = name;
_key = config["key"];
_vector = config["vector"];
_cryptoProvider.Key = HexToByte(_key);
_cryptoProvider.IV = HexToByte(_vector);
}
/// <summary>
/// Encrypt the specific Node
/// </summary>
/// <param name="node">XML node to encrypt</param>
/// <returns>encrypted node</returns>
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;
}
/// <summary>
/// decrypt the specific node
/// </summary>
/// <param name="encryptedNode">Encrypted node</param>
/// <returns>clear text xml node</returns>
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
/// <summary>
/// Encrypts the XML string
/// </summary>
/// <param name="encryptValue">clear text value</param>
/// <returns>encrypted value</returns>
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);
}
/// <summary>
/// Decrypts the text
/// </summary>
/// <param name="encryptedValue">encrypted text</param>
/// <returns>clear text</returns>
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
/// <summary>
/// Converts a byte array to a hexadecimal string
/// </summary>
/// <param name="byteArray">byte array</param>
/// <returns>hex string</returns>
private string ByteToHex(byte[] byteArray)
{
string outString = "";
foreach (Byte b in byteArray)
outString += b.ToString("X2");
return outString;
}
/// <summary>
/// Converts a hexadecimal string to a byte array
/// </summary>
/// <param name="hexString">hex value</param>
/// <returns>byte array</returns>
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
}
您需要在 web.config 文件的 configuration 节点下包含以下内容
<configProtectedData>
<providers>
<add name="MyProtectedProvider"
type="MyNamespace.MyProtectedConfigProvider,MyProtectedConfigProvider,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=4653ckjfie250a45e9"
key="################################################"
vector="################"
/>
</providers>
</configProtectedData>
现在,使用命令行实用程序并提供此自定义提供程序的名称,我们可以加密/解密 web.config 文件的节。如果需要,密钥和向量在 Web Farm 实现的情况下可以相同。
注意:这甚至会加密物理上位于不同文件并引用在 web.config 文件中的节。
例如
<appSettings configSource="configurations/appSettings.config"/>
这将进入 appSettings
文件并加密该节。
结论
这段代码可以帮助您创建自己的加密提供程序来加密/解密 web.config 中的节。当您需要在 Web Farm 方案中加密 web.config 的节时,这可能很有用。这也有助于使用您自己的加密机制。