背景
在程序或服务开发过程中,我们通常会把一些程序需要用到的常量数据配置在web.config或app.config文件中,通常配置到这些文件中的Key与Value都是明文的,但有时候我们并不希望这些配置让他人知道。
在这种情况下,我们可以使用ASP.NET Encrypt和Decrypt来对配置文件进行加密,不影响程序使用,但又不被他人知道配置的具体内容。
环境
- Windonw 7 / Windows Server 2008
- .Net Framework 4.0
- IIS
以上环境准备好后,在搭建好的IIS上创建三个站点 WebSite1, WebSite2, WebSite3
工具
- asp.net_regiis.exe
- vs 2010 tool
- sn.exe
- gacutil.exe
asp.net_regiis.exe位于路径C:\Windows\Microsoft.NET\Framework64\v4.0.30319
使用管理员身份运行cmd.exe
Start --> All Programs --> Microsoft Visual Studio 2010 --> Visual Studio Tools --> Visual Studio x64 Win64 Command Prompt (2010)(run as administrator)
sn, gacutil 在VS 2010 tool中可直接使用
Providers in .NET Framework
-
DpapiProtectedConfigurationProvider
uses the Windows Data Protected API(DPAPI) to encrypt and Decrypt data. -
RsaProtectedConfigurationProvider
useed the RSA encryption algorithm to encrypt and Decrypt data.
Providers means Protected configuration Providers
Machine-Level and User-Level
Machine-Level
available to all users
Machine-level 的Key对所有管理员用户有效果,但也受ACLs的约束
User-Level
available only to the user that created the key container.
stored with the Windonw user profile for a particular user
userd to encrypt and decrypt information for applications that run under that specific user identity.
user-level 的Key是与用户账号绑定的,用户被删除时,key也被删除
这里所讲的avalliable是指能够加密和解密
Tool and Parameters
Tool
asp.net_regiis.exe
encrypt parameters
-pe the name of the configuraiton element to be encrypt
-app identity the application for which the web.config file will be encrypted
-site identity which web site the application is a part of
-prov identity the name of the ProtectedConfigurationProvider that will preform the encryption and decryption.
pe, app 是必须要指定的值
site默认值为1, prov默认使用defaultProvider
decrypt parameters
-pd the name of the configuration element to be decrypted.
-app identify the application for which the web.config file will be encrypted
-site identify which Web site the application is a part of
-prov not need to specify
在解密时不需要使用prov来指定ProtectedConfigurationProvider,because that information is read from the configProtectionProvider attribute of the protected configuration section.
Encrypting Website’s Web.config
在VS Tool中输入以下命令
aspnet_regiis -pef "connectionStrings" E:\webSite1
或
aspnet_regiis -pe "connectionStrings" -app "/WebSite1" -site "WebSite1"
需要为WebSite1添加虚拟目录
或
aspnet_regiss -pe "connectionStrings" -app "/WebSite1" -site "WebSite1" -prov DataProtectionConfigurationProvider
需要为WebSite1添加虚拟目录,指定Provider
解密
aspnet_regiis -pd "connectionStrings" -app "/WebSite1" -site "WebSite1"
Create a RSA Key Container
Tool
aspnet_regiis
Parameters
-pc : the name of the key container used by the RsaProtectedConfigurationProvider specified in the configProtectedData section of web.config file
-exp : ensure that RSA key container can be exported
Web.config的配置
<configProtectedData>
<providers>
<add name="CustomerProvider" keyContainerName="SampleKeys" useMachineContainer="true" description="Users RsaCryptoSErviceProvider to encrypt and decrypt" type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=4.0.0.0, Cultuer=neutral, PublicKeyToken=b03f5f7f11d50a3a">
</providers>
</configProtectedData>
以上配置中的KeyContainerName="true",表示使用Machine-level, false表示使用user-level
加密时使用以下命令
aspnet_regiis -pe "connectionStrings" -app "/WebSite2" -site "WebSite2" -prov "CustomeProvider"
Exporting a RSA Key Container
使用命令
aspnet_regiis -px "SampleKeys" E:\MachineSmapleKey.xml -pri
Importing a RSA Key Container
aspnet_regiis -pi "MyKeys" keys.xml -pku
Deleting a RSA Key Container
aspnet_regiis -pz "MyKeys"
Custome Provider Type
Implementing a Protected Configuration Provider
- Algorithm
an algorithm other than those available with the RSA or DPAPI providers - Required Classes
ProtectedConfigurationProvider class from the System.Configuration namespace
ProviderBase class from the System.Configuration.Provider namespace - Required Members
Initialize method (from ProviderBase)
Encrypt method (from ProtectedConfigurationProvider)
Decrypt method (from ProtectedConfigurationProvider)
Build Protected Configuration Provider
- Generate a strong-name key pair
sn -k keys.snk
- Create a program file named TripleDESProtectedConfigurationProvider
using System.Xml;
using System.Security.Cryptography;
using System.IO;
using System.Text;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System.Configuration;
namespace AA.BB.ProtectedConfiguration
{
public class TripleDESProtectedConfigurationProvider : ProtectedConfigurationProvider
{
private TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
private string pKeyFilePath;
private string pName;
public string KeyFilePath
{
get { return pKeyFilePath; }
}
//
// ProviderBase.Name
//
public override string Name
{
get { return pName; }
}
//
// ProviderBase.Initialize
//
public override void Initialize(string name, NameValueCollection config)
{
pName = name;
pKeyFilePath = config["keyFilePath"];
ReadKey(KeyFilePath);
}
//
// ProtectedConfigurationProvider.Encrypt
//
public override XmlNode Encrypt(XmlNode node)
{
string encryptedData = EncryptString(node.OuterXml);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml("<EncryptedData>" + encryptedData + "</EncryptedData>");
return xmlDoc.DocumentElement;
}
//
// ProtectedConfigurationProvider.Decrypt
//
public override XmlNode Decrypt(XmlNode encryptedNode)
{
string decryptedData = DecryptString(encryptedNode.InnerText);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(decryptedData);
return xmlDoc.DocumentElement;
}
//
// EncryptString
// Encrypts a configuration section and returns the encrypted
// XML as a string.
//
private string EncryptString(string encryptValue)
{
byte[] valBytes = Encoding.Unicode.GetBytes(encryptValue);
ICryptoTransform transform = des.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);
}
//
// DecryptString
// Decrypts an encrypted configuration section and returns the
// unencrypted XML as a string.
//
private string DecryptString(string encryptedValue)
{
byte[] valBytes = Convert.FromBase64String(encryptedValue);
ICryptoTransform transform = des.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);
}
//
// CreateKey
// Generates a new TripleDES key and vector and writes them
// to the supplied file path.
//
public void CreateKey(string filePath)
{
des.GenerateKey();
des.GenerateIV();
StreamWriter sw = new StreamWriter(filePath, false);
sw.WriteLine(ByteToHex(des.Key));
sw.WriteLine(ByteToHex(des.IV));
sw.Close();
}
//
// ReadKey
// Reads in the TripleDES key and vector from the supplied
// file path and sets the Key and IV properties of the
// TripleDESCryptoServiceProvider.
//
private void ReadKey(string filePath)
{
StreamReader sr = new StreamReader(filePath);
string keyValue = sr.ReadLine();
string ivValue = sr.ReadLine();
des.Key = HexToByte(keyValue);
des.IV = HexToByte(ivValue);
}
//
// ByteToHex
// Converts a byte array to a hexadecimal string.
//
private string ByteToHex(byte[] byteArray)
{
string outString = "";
foreach (Byte b in byteArray)
outString += b.ToString("X2");
return outString;
}
//
// HexToByte
// Converts a hexadecimal string to a byte array.
//
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;
}
}
}
- Compile the code and assign the resulting assembly with the strong-name key
csc /out:TripleDESProtectedConfigurationProvider.dll /t:library TripleDESProtectedConfigurationProvider.cs /r:System.Configuration.dll /keyfile:keys.snk
- Install the assembly in the GAC(global assembly cach)
gacutil -i TripleDESProtectedConfigurationProvider.dll
Use a Custom Provider type
-
Generate Key File
CreateKey.exe E:\ASP\Keys.txt
-
Modify the configProtectedData Section of the Web.config
<configProtectedData>
<providers>
<add name="SampleProvider" useMachineContainer="true" type="AA.BB.TripleDESProtectedConfigurationProvider TripleDESProtectedConfigurationProvider Version=0.0.0.0, Cultuer=neutral PublicKeyToken=b06675f7f11d50a3a",description="Users RsaCryptoSErviceProvider to encrypt and decrypt" keyFilePath="E:\ASP\Key" >
</providers>
</configProtectedData>
网友评论