受保护配置概述
可以使用受保护配置来加密 Web 应用程序配置文件(如 Web.config 文件)中的敏感信息(包括用户名和密码、数据库连接字符串和加密密钥)。对配置信息进行加密后,即使攻击者获取了对配置文件的访问,也可以使攻击者难以获取对敏感信息的访问,从而改进应用程序的安全性。
例如,未加密的配置文件中可能包含一个指定用于连接到数据库的连接字符串的节,如下面的示例所示:
<configuration> <connectionStrings> <add name="SampleSqlServer" connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;" /> </connectionStrings> </configuration>
使用受保护配置对连接字符串值进行加密的配置文件不以明文形式显示连接字符串,而是以加密形式存储它们,如下面的示例所示:
<configuration> <connectionStrings 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>RXO/zmmy3sR0iOJoF4ooxkFxwelVYpT0riwP2mYpR3FU+r6BPfvsqb384pohivkyNY7Dm4lPgR2bE9F7k6TblLVJFvnQu7p7d/yjnhzgHwWKMqb0M0t0Y8DOwogkDDXFxs1UxIhtknc+2a7UGtGh6Di3N572qxdfmGfQc7ZbwNE= </CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>KMNKBuV9nOid8pUvdNLY5I8R7BaEGncjkwYgshW8ClKjrXSM7zeIRmAy/cTaniu8Rfk92KVkEK83+UlQd+GQ6pycO3eM8DTM5kCyLcEiJa5XUAQv4KITBNBN6fBXsWrGuEyUDWZYm6Eijl8DqRDb11i+StkBLlHPyyhbnCAsXdz5CaqVuG0obEy2xmnGQ6G3Mzr74j4ifxnyvRq7levA2sBR4lhE5M80Cd5yKEJktcPWZYM99TmyO3KYjtmRW/Ws/XO3z9z1b1KohE5Ok/YX1YV0+Uk4/yuZo0Bjk+rErG505YMfRVtxSJ4ee418ZMfp4vOaqzKrSkHPie3zIR7SuVUeYPFZbcV65BKCUlT4EtPLgi8CHu8bMBQkdWxOnQEIBeY+TerAee/SiBCrA8M/n9bpLlRJkUb+URiGLoaj+XHym//fmCclAcveKlba6vKrcbqhEjsnY2F522yaTHcc1+wXUWqif7rSIPhc0+MT1hB1SZjd8dmPgtZUyzcL51DoChy+hZ4vLzE= </CipherValue> </CipherData> </EncryptedData> </connectionStrings>
在对页进行请求时,.NET Framework 对自动连接字符串信息进行解密,并使其可供应用程序使用。
注意 |
---|
不能使用受保护配置来加密配置文件的 configProtectedData 节。也不能使用受保护配置来加密不使用节处理程序的配置节或者属于托管密码配置的节。下面是不能使用受保护配置进行加密的配置节的列表:processModel、runtime、mscorlib、startup、system.runtime.remoting、configProtectedData、satelliteassemblies、cryptographySettings、cryptoNameMapping 和 cryptoClasses。建议您使用其他方法(如 ASP.NET 设置注册表控制台应用程序 Aspnet_setreg.exe 工具)来加密敏感信息,以保护这些配置节中的敏感信息。有关 ASP.NET 设置注册表控制台应用程序 (Aspnet_setreg.exe) 的信息,请参见 Microsoft 知识库中的文章 Q329290“How to use the ASP.NET utility to encrypt credentials and session state connection strings”(如何使用 ASP.NET 实用工具加密凭据和会话状态连接字符串),知识库网址为 Microsoft 支持网站。 |
安全注意 |
---|
在将加密配置信息加载到应用程序使用的内存中时,会对这些信息进行解密。如果应用程序的内存受到安全威胁,则受保护配置节中的敏感信息可能也会受到安全威胁。 |
使用受保护配置
可以使用 ASP.NET IIS 注册工具 (Aspnet_regiis.exe) 或 System.Configuration 命名空间中的受保护配置类来管理受保护配置。
Aspnet_regiis.exe 工具(位于 %SystemRoot%\Microsoft.NET\Framework\versionNumber 文件夹中)中包括用于下列内容的选项:对 Web.config 文件的节进行加密和解密、创建或删除密钥容器、导出和导入密钥容器信息以及管理对密钥容器的访问。
通过使用 ProtectedConfigurationProvider 类可以对 Web.config 文件的内容进行加密和解密。下面的列表描述了包括在 .NET Framework 中的受保护配置提供程序:
-
DPAPIProtectedConfigurationProvider。使用 Windows 数据保护 API (DPAPI) 对数据进行加密和解密。
-
RsaProtectedConfigurationProvider。使用 RSA 加密算法对数据进行加密和解密。
这两个提供程序都提供对数据的强加密;但是,如果您打算在多台服务器(如网络场)上使用同一个加密配置文件,则只有使用 RsaProtectedConfigurationProvider 才能导出用于对数据进行加密的加密密钥,并在另一台服务器上导入它们。
您可以通过在应用程序的 Web.config 文件中配置它来指定要使用哪个 ProtectedConfigurationProvider,也可以使用在 Machine.config 文件中配置的 ProtectedConfigurationProvider 实例之一。
既可以自行指定受保护配置提供程序,也可以使用内置于 ASP.NET 的提供程序之一。默认情况下,Machine.config 文件指定了下列受保护配置提供程序:
1.名为 RsaProtectedConfigurationProvider 的 RsaProtectedConfigurationProvider 实例。该提供程序配置为默认提供程序。
2.名为 DataProtectionConfigurationProvider 的 DPAPIProtectedConfigurationProvider 实例。
<!--指定受保护的配置提供程序-->
在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG目录下找到Machine.config将下面代码段复制到web.config 的<configuration>与</configuration>之间.即可使用默认提供程序了.
<configProtectedData defaultProvider="RsaProtectedConfigurationProvider" > |
使用自定义的提供程序
在配置文件的 configProtectedData 节中指定受保护配置提供程序。如果要使用自定义的提供程序,可以使用 providers 元素的 add 元素声明新的提供程序实例。可以使用 configProtectedData 元素的 defaultProvider 属性将该提供程序实例标识为默认的提供程序。
下面的示例使用名称 SampleProvider 配置 RsaProtectedConfigurationProvider 实例,并将其设置为默认的提供程序。
<configuration> <configProtectedData defaultProvider="myProvider"><--! 指定自定义的提供程序myProvider为默认提供程序--> <providers> <add name="myProvider" <--! 指定自定义的提供程序myProvider--> type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" keyContainerName="myKey" <--!自定义的RSA 密钥容器myKey,在后面创建自定义密钥部分讲解--> useMachineContainer="true" /> </providers> </configProtectedData> </configuration>
受保护配置提供程序选项
在配置文件中,每个受保护配置提供程序都公开了可以使用该提供程序的声明属性设置的选项。所有的提供程序都需要提供程序实例的 type 和 description 属性,以及 keyName。除此之外,这些选项对于每种提供程序类型都是唯一的。
下表描述了 RSAProtectedConfigurationProvider 的配置选项。
属性 | 说明 | ||
---|---|---|---|
type | 受保护配置提供程序的类型。下面的示例演示 RsaProtectedConfigurationProvider 的类型定义: type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0. 0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d0a3a, processorArchitecture=MSIL" | ||
description | 提供程序实例的说明。 | ||
keyContainerName | 用于加密或解密 Web.config 文件内容的 RSA 密钥容器的名称。
| ||
useMachineContainer | 如果 RSA 密钥容器是计算机级密钥容器,则为 true;如果 RSA 密钥容器是用户级密钥容器,则为 false。有关更多信息,请参见使用受保护的配置加密配置信息。 | ||
useOAEP | 如果加密和解密时使用最优非对称加密填充 (OAEP),则为 true;否则为 false。有关更多信息,请参见 RSAOAEPKeyExchangeFormatter 属性。 | ||
cspProviderName | Windows 密码 API (crypto API) 密码服务提供程序 (CSP) 的名称。有关更多信息,请参见 ProviderName。 |
下表描述了 DPAPIProtectedConfigurationProvider 的配置选项。
属性 | 说明 |
---|---|
type | 受保护配置提供程序的类型。下面的示例演示 DPAPIProtectedConfigurationProvider 的类型定义: type="System.Configuration.DPAPIProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d0a3a, processorArchitecture=MSIL" |
description | 提供程序实例的说明。 |
keyEntropy | 应用程序特定的值,将该值包含在加密密钥中可以防止其他应用程序对加密信息进行解密。有关更多信息,请参考 Windows 数据保护 API (DPAPI) 的 CryptProtectData 方法中的 OptionalEntropy 参数。 |
useMachineProtection | 如果为 true,则使用计算机特定的保护;如果为 false,则使用用户帐户特定的保护。如果为 true,计算机上运行的任何进程都不会保护数据。因此,建议您使用访问控制列表 (ACL) 对加密数据的访问进行限制。有关更多信息,请参见 Windows 数据保护 API (DPAPI) 中 CryptProtectData 方法的 dwFlags 参数的 CRYPTPROTECT_LOCAL_MACHINE 值。 |
授予对 RSA 加密密钥的读取权限
打开文本编辑器,然后将下面的代码复制到一个新文件中。
<%@ Page Language="VB" %>
<%
Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name)
%>
C# 复制代码
<%@ Page Language="C#" %>
<%
Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
%>
因为将在本演练中使用 IIS,所以不要对您的站点身份验证使用模拟。即只对该演练使用匿名身份验证作
加密 Web.config 文件的节
在文本编辑器中,打开应用程序的 Web.config 文件。
<configuration>
<connectionStrings>
<add name="SqlServices" connectionString="Data Source=localhost;Integrated
</connectionStrings>
decryptionKey="FBF50941F22D6A3B229EA593F24C41203DA6837F1122EF17" />
</configuration>
关闭 Web.config 文件。
<configuration>
<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>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
<machineKey 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>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
</CipherValue>
</CipherData>
</EncryptedData>
</machineKey>
</configuration>
关闭 Web.config 文件。
查看已解密的配置值
打开文本编辑器,然后将下面的 ASP.NET 代码复制到一个新文件中。
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Configuration" %>
<%@ Import Namespace="System.Web.Configuration" %>
<script runat="server">
ConnectionStringsGrid.DataBind()
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
Dim key As MachineKeySection = _
CType(config.GetSection("system.web/machineKey"), MachineKeySection)
DecryptionKey.Text = key.DecryptionKey
ValidationKey.Text = key.ValidationKey
<html>
<P>
MachineKey.DecryptionKey = <asp:Label runat="Server" id="DecryptionKey" /><BR>
MachineKey.ValidationKey = <asp:Label runat="Server" id="ValidationKey" />
</html>
C# 复制代码
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Configuration" %>
<%@ Import Namespace="System.Web.Configuration" %>
<script runat="server">
{
ConnectionStringsGrid.DataSource = ConfigurationManager.ConnectionStrings;
ConnectionStringsGrid.DataBind();
MachineKeySection key =
(MachineKeySection)config.GetSection("system.web/machineKey");
DecryptionKey.Text = key.DecryptionKey;
ValidationKey.Text = key.ValidationKey;
}
<html>
<P>
MachineKey.DecryptionKey = <asp:Label runat="Server" id="DecryptionKey" /><BR>
MachineKey.ValidationKey = <asp:Label runat="Server" id="ValidationKey" />
</html>
解密 Web 配置节
通过运行带有 -pd 选项的 aspnet_regiis.exe 对已加密的 Web.config 文件内容进行解密
=========================创建和导出 RSA 密钥容器 ====================
创建自定义的计算机级的 RSA 密钥容器
通过运行带有下列选项的 aspnet_regiis.exe 来创建计算机级别的新 RSA 密钥容器:
下面的命令授予 NETWORK SERVICE 帐户对计算机级别的 "MyKeys" RSA 密钥容器的访问权限。
指定受保护的配置提供程序
添加 <configProtectedData> 节,其中包括名为 "MyProvider" 的 RsaProtectedConfigurationProvider 类的实例,这个类使用名为 "MyKeys" 的计算机级别 RSA 密钥容器,如下面的示例所示。
<configuration> |
加密 Web.config 文件的节
既然已经指定使用 "MyKeys" RSA 密钥容器的 RsaProtectedConfigurationProvider 类的实例,并且 ASP.NET 应用程序的标识能够读取 "MyKeys",请使用 "MyKeys" 对 ASP.NET 应用程序的 Web.config 文件的节进行加密,然后 ASP.NET 在处理 Web.config 文件时会对文件的节进行解密。
对 Web.config 文件的 <connectionStrings> 节进行加密
在命令提示处,运行带有下列选项的 aspnet_regiis.exe:
-pe 选项,后跟 "connectionStrings",用于对应用程序的 Web.config 文件的 <connectionStrings> 元素进行加密。
-app 选项,用于标识应用程序的名称。
-prov 选项后跟 "MyProvider",用于标识在上述步骤中 Web.config 文件中指定的 RsaProtectedConfigurationProvider 提供程序。
例如,下面的命令将加密 MyApplication 应用程序的 Web.config 文件的 <connectionStrings> 节。
aspnet_regiis -pe "connectionStrings" -app "/MyApplication" -prov "MyProvider"
导出和导入 RSA 密钥容器
可以将 RSA 密钥容器导出到一个 XML 文件作为密钥值的备份副本,或者将密钥容器复制到其他 Web 服务器,这些服务器将承载包括已加密的 Web.config 文件的应用程序的副本。如果没有用于加密 Web.config 文件的特定 RSA 密钥容器,则 ASP.NET 将无法对已加密的配置值进行解密。
查看已解密的配置值
在命令提示处,运行带有下列选项的 aspnet_regiis.exe:
-px 选项后跟 "MyKeys",它是在本演练的前一部分“创建自定义的 RSA 密钥容器”中创建的 RSA 密钥容器的名称。
将密钥容器导出到的 .xml 文件的路径。
-pri 选项,用于确保已导出私钥信息。否则,导出的密钥信息只能对信息进行加密,而不能进行解密。
例如,下面的命令将名为 "MyKeys" 的计算机级别 RSA 密钥容器导出到名为 keys.xml 的 .xml 文件,该文件位于 C 驱动器的根目录下。
aspnet_regiis -px "MyKeys" "c:\keys.xml" -pri
您现在具有使用已加密的 Web.config 文件将应用程序复制到独立 Web 服务器所需的所有信息。
如果要使用已加密的 Web.config 文件将应用程序复制到独立的 Web 服务器中,请转到步骤 4。
如果您没有第二台需要复制 Web 应用程序的 Web 服务器,并且要继续本演练,请完成下面的步骤从 Web 服务器中删除 RSA 密钥容器。然后,将这台 Web 服务器视为第二台 Web 服务器。
若要删除 RSA 密钥容器,请在命令提示处运行带有 -pz 开关的 aspnet_regiis.exe,后跟 "MyKeys"。
例如,下面的命令将删除 "MyKeys":
aspnet_regiis -pz "MyKeys"
转到步骤 5。
将包括已加密的 Web.config 文件的 Web 应用程序复制到另一台 Web 服务器。
如果您不确定如何将 Web 应用程序复制到第二台服务器,请将现有应用程序中的所有文件夹和内容复制到第二台 Web 服务器中,然后按照如何:在 IIS 中创建和配置虚拟目录中的步骤将应用程序标识为 Web 应用程序。
在第二台服务器上,打开命令提示窗口,然后输入以下命令将目录更改为 .NET Framework 2.0 版目录:
cd \WINDOWS\Microsoft.Net\Framework\v2.0.*
将包含已导出的 RSA 密钥容器的 .xml 文件复制到第二台 Web 服务器上的 .NET Framework 2.0 版的目录中。
在此演练中,将 keys.xml 文件复制到驱动器 C 的根目录下。
在第二台 Web 服务器的命令提示处,运行带有下列选项的 aspnet_regiis.exe:
-pi 选项,后跟已导出的密钥容器的名称 "MyKeys",用于导入 RSA 密钥容器。
包含已导出的密钥容器的 .xml 文件的路径
例如,下面的命令会导入名称为 "MyKeys" 的 RSA 密钥容器。
aspnet_regiis -pi "MyKeys" "c:\keys.xml"
在第二台 Web 服务器上,删除包含已导出的 RSA 密钥容器的 .xml 文件的副本。
在第二台 Web 服务器上,确定 ASP.NET 应用程序的标识,并按照本演练的前一部分“授予对 RSA 加密密钥的读取权限”中的步骤授予该标识对已导入的 RSA 密钥容器的访问权限。
在第二台 Web 服务器上,遵循上述部分中的步骤查看已加密 Web.config 文件中的已解密配置设置。