保护连接字符串及其它设置信息,轻松加密ASP

导言:

**一、 简介

  ASP.NET应用程序的设置信息通常都存储在一个名为Web.config的XML文件里。在教程的前面部分我们已经好几次修改过Web.config文件了.比如在第一章,我们创建名为Northwind的数据集时,数据库连接字符串信息自动的添加到Web.config文件的<connectionStrings>节点.再后来,在第3章里,我们手动更新了Web.config文件,添加了一个<pages>元素,对所有的ASP.NET页面运用DataWebControls主题.

**  当创建ASP.NET 2.0应用程序时,开发者通常都把敏感的配置信息存储在Web.config文件中。最典型的示例就是数据库连接字符串,但是包括在Web.config文件中的其它敏感信息还包括SMTP服务器连接信息和用户凭证数据,等等。尽管默认情况下可以配置ASP.NET以拒绝所有对扩展名为.config的文件资源的HTTP请求;但是,如果一个黑客能够存取你的web服务器的文件系统的话,那么,Web.config中的敏感信息仍然能够被窃取。例如,也许你不小心允许匿名FTP存取你的网站,这样以来就允许一个黑客简单地通过FTP协议下载你的Web.config文件。

  由于Web.config文件包含了敏感的信息,比如连接字符串.所以确保Web.config文件内容的安全性是很重要的,对未经授权的访问者应隐藏这些敏感信息.默认情况下,对.config后缀名的文件的任何HTTP请求都由ASP.NET引擎来处理,它将返回“This
type of page is not
served”的信息,如图1所示.这意味着访问者无法通过在其浏览器的地址栏键入‘.

  幸好,通过允许加密Web.config文件中选择的部分,例如<connectionStrings>节,或你的应用程序使用的一些定制config节,ASP.NET 2.0有助于缓解这个问题。配置部分能够很容易地使用编码或aspnet_regiis.exe(一个命令行程序)预以加密。一旦被加密,Web.config设置即可避开”虎视眈眈”的眼睛。而且,当以编程方式从你的ASP.NET页面中检索加密的配置设置时,ASP.NET会自动地解密它读取的加密部分。简言之,一旦配置信息被加密,你就不需要在你的应用程序中编写任何其它代码或采取任何进一步的行为来使用该加密数据。

图片 1
图1:通过浏览器访问Web.config将返回“This type of page is not
served”的信息

  在本文中,我们将讨论如何以编程方式加密和解密该配置设置部分,并且分析一下命令行程序aspnet_regiis.exe的使用。然后,我们将评估ASP.NET 2.0提供的加密选项。另外,还会简短地讨论一下如何加密ASP.NET版本1.x中的配置信息。

  但是如果某个攻击者找到其它方法来访问你的Web.config文件的内容又怎么办呢?他会做怎样的修改?我们又采取怎样的步骤来保护Web.config文件的这些信息呢?幸运的是,Web.config文件的绝大多数节点并不包含敏感信息.如果攻击者知道你的ASP.NET页面使用的默认的主题的名字又会搞哪些破坏呢?

  二、 前提

  Web.config文件的某些节点包含了敏感信息,比如:connection strings,
user names, passwords, server names, encryption
keys等等.我们能在下面的这些节点找到这些信息:

  在我们开始探讨如何加密ASP.NET 2.0配置信息之前,请记住下列几点:

.<appSettings>
.<connectionStrings>
.<identity>
.<sessionState>

  1. 所有形式的加密都会包含某种秘密,而当加密和解密数据时都要使用这一秘密。对称加密算法在加密和解密一个消息时使用同一把密钥,而非对称加密算法对于加密和解密却使用不同的密钥。无论使用哪种技术,最重要的还是看解密密钥的安全保存程度。

  在本文我们将考察保护这些敏感信息的技术.就像我们将看到的那样,.NET
Framework
2.0版本包含了一个保护配置系统,我们可以使用它很容易地对选定的配置节点进行加密和解密.

  2. ASP.NET 2.0提供的配置加密技术的设计目的在于,力图阻止能够以某种方式检索你的配置文件的黑客的入侵。其实现思想是,如果在黑客的计算机上有你的Web.config文件;那么,他不能破解该加密的部分。然而,当web服务器上的一个ASP.NET页面从一个加密的配置文件请求信息时,该数据必须被解密才能使用(并且这时不需要你编写任何代码)。因此,如果一个黑客能够把一个能够查询配置文件并显示它的结果的ASP.NET web页面上传到你的系统,那么,他就能够以普通文本方式观看被加密的设置。(详细情况请参考本文提供的示例ASP.NET页面,它展示了加密和解密Web.config文件中各部分的方法;如你所见,一个ASP.NET页面能够存取(并显示)该加密数据的普通文本形式)

  注意:在本文结尾部分,我们将看到微软对从一个ASP.NET应用程序连接到数据库时的建议.除了对连接字符串进行加密外,我们还可以连接到一个处于“安全模式”的数据库使你的系统更强大.

  3. 加密和解密配置信息需要付出一定的性能代价。因此,通常是仅加密包含敏感信息的配置部分。比如说,可能不需要加密<compilation>或<authorization>配置部分。

第一步:考察ASP.NET 2.0的保护配置选项

  三、 加密何种信息

ASP.NET
2.0包含一个保护配置系统以对配置信息进行加密和解密.这些方法包含在.NET
Framework,可用来编程加密和解密配置信息.该保护配置系统使用provider
model模式.它允许开发者选择执行哪种加密.

  在我们分析如何加密ASP.NET 2.0配置信息前,让我们首先来看一下能够加密什么配置信息。使用.NET框架2.0提供的库,开发人员能够加密在Web.config或machine.config文件中的绝大多数的配置部分。这些配置部分是一些作为<configuration>或<system.web>元素子结点的XML元素。例如,下面的示例Web.config文件中含有三个配置设置,显式地定义为:

.NET Framework包含了2种protected configuration providers:

<connectionStrings>,<compilation>和<authentication>。
<?xml version=”1.0″?>
<configuration xmlns=”
<connectionStrings>
 <add name=”MembershipConnectionString” connectionString=”connectionString”/>
</connectionStrings>
<system.web>
 <compilation debug=”true”/>
 <authentication mode=”Forms” />
</system.web>
  这些节中的每一个都可以有选择地被加密,或者通过编程方式或通过aspnet_regiis.exe(一个命令行工具)实现。当被加密时,加密后的文本直接存储在配置文件中。例如,如果我们要加密上面的<connectionStrings>节,那么结果Web.config文件可能看起来如下所示:(注意:篇幅所限,我们省略了一大块<CipherValue>)

.RSAProtectedConfigurationProvider
:加密和解密时使用不对称RSA运算法则(RSA algorithm)

<?xml version=”1.0″?>
<configuration xmlns=”
<connectionStrings configProtectionProvider=”DataProtectionConfigurationProvider”>
<EncryptedData>
 <CipherData>
  <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAed…GicAlQ==</CipherValue>
 </CipherData>
</EncryptedData>
</connectionStrings>
<system.web>
 <compilation debug=”true”/>
 <authentication mode=”Forms” />
</system.web>
  另外,存在一些你不能使用这个技术加密的配置部分:

.DPAPIProtectedConfigurationProvider:加密和解密时使用Windows Data
Protection API (DPAPI)

  · <processModel>
  · <runtime>
  · <mscorlib>
  · <startup>
  · <system.runtime.remoting>
  · <configProtectedData>
  · <satelliteassemblies>
  · <cryptographySettings>
  · <cryptoNameMapping>
  · <cryptoClasses>

由于保护配置系统执行的是provider
design模式,因此我们可以创建自己的protected configuration
provider并运用到自己的程序里.具体过程可参阅文章《Implementing a
Protected Configuration
Provider》()

  为了加密这些配置部分,你必须加密这些值并把它存储在注册表中。存在一个aspnet_setreg.exe命令行工具可以帮助你实现这一过程;我们将在本文后面讨论这个工具。

  RSA providers 和 DPAPI
providers在加密和解密时使用“密匙”(keys),这些“密匙”可以存储在“机器级”(Machine-level)和“用户级”(user-level).机器级密匙在这种情况下很理想:每个web应用程序都运行在自己专有的服务器上,或某个服务器上的多个应用程序共享同样的加密信息.而用户级密匙在共享服务器环境里是比较理想的安全选择.此时,同服务器上的其它程序不能对你加密的配置信息进行解密.

  【提示】Web.Config和Machine.Config之区别:

  本教程的示例将使用DPAPI
provider和机器级密匙.具体来说,我们将对Web.config文件里的<connectionStrings>节点进行加密.对RSA
provider以及用户级密匙的更多信息请参考本文结束部分的外延阅读资料.

  Web.config文件指定针对一个特定的web应用程序的配置设置,并且位于应用程序的根目录下;而machine.config文件指定所有的位于该web服务器上的站点的配置设置,并且位于$WINDOWSDIR$\Microsoft.Net\Framework\Version\CONFIG目录下。

  注意:RSAProtectedConfigurationProvider
和DPAPIProtectedConfigurationProvider
providers在machine.config文件里被分别组册成RsaProtectedConfigurationProvider
和DataProtectionConfigurationProvider。当我们对配置信息进行加密或解密时我们需要提供相应的provider名称(即RsaProtectedConfigurationProvider

DataProtectionConfigurationProvider);而不是实际的类型名(即RSAProtectedConfigurationProvider
和 DPAPIProtectedConfigurationProvider).
你可以在$WINDOWS$/Microsoft.NET/Framework/version/CONFIG文件夹里找到machine.config文件.

  四、加密选项

第二步:通过编程加密和解密配置节点

  开发人员可以使用ASP.NET 2.0提供程序模型来保护配置节信息,这允许任何实现都可以被无缝地插入到该API中。.NET框架2.0中提供了两个内置的提供程序用于保护配置节信息:

  使用某个provider,我们只需要很少的几行代码就可以对某个配置节点加密或解密.这些代码仅仅需要引用相应的配置节点,调用其ProtectSection
或 UnprotectSection方法,再调用Save方法来执行.另外,.NET
Framework包含了一个很有用的命令行功能来进行加密和解密,我们将在第3步考察该功能.

  · Windows数据保护API(DPAPI)提供程序(DataProtectionConfigurationProvider):这个提供程序使用Windows内置的密码学技术来加解密配置节。默认情况下,这个提供程序使用本机的密钥。你还能够使用用户密钥,但是这要求进行一点定制。

  为了便于演示,我们需要创建一个包含按钮的ASP.NET页面,以便于对Web.config文件的<connectionStrings>节点进行加密和解密.

  · RSA保护的配置提供程序(RSAProtectedConfigurationProvider):使用RSA公钥加密来加解密配置节。使用这个提供程序,你需要创建存储用于加解密配置信息的公钥和私钥的密钥容器。你能够在一个多服务器场所下使用RSA,这只要创建可输出的密钥容器即可。
当然,如果需要的话,你还能够创建自己的保护设置提供程序。

  打开AdvancedDAL文件夹里的EncryptingConfigSections.aspx页面,拖一个TextBox控件到页面,设其ID为WebConfigContents;TextMode属性为MultiLine;Width和Rows属性分别为95%

15.该TextBox控件用于显示Web.config文件的内容,以查看其内容是否已经加密了.当然,在现实程序里,我们不可能将Web.config文件的内容显示出来.

  在本文中,我们仅讨论使用DPAPI提供程序使用机器级密钥。到目前为止,这是最简单的方法,因为它不请求创建任何密钥或密钥容器。当然,其消极的一面在于:一个加密的配置文件仅能够用于首先实现加密的web服务器上;而且,使用机器密钥将允许加密的文本能够被web服务器上的任何网站所解密。

  在该TextBox控件下面添加2个Button控件,ID分别为EncryptConnStrings 和
DecryptConnStrings;设其Text属性为“Encrypt Connection Strings” 和
“Decrypt Connection Strings”.

  五、以编程方式加密配置部分

此时你的界面看起来和下面的差不多:

  System.Configuration.SectionInformation类对一个配置节的描述进行了抽象。为了加密一个配置节,只需要简单地使用SectionInformation类的ProtectSection(提供程序)方法,传递你想使用的提供程序的名字来执行加密。为了存取你的应用程序的Web.config文件中的一个特定的配置节,你可以使用WebConfigurationManager类(在System.Web.Configuration命名空间中)来引用你的Web.config文件,然后使用它的GetSection(sectionName)方法返回一个ConfigurationSection实例。最后,你可以经由ConfigurationSection实例的SectionInformation属性得到一个SectionInformation对象。

图片 2
图2:在页面上添加一个TextBox控件和2个Button控件

  下面,我们通过一个简单的代码示例来说明问题:

  接下来,在页面初次登录时我们需要在ID为WebConfigContents的TextBox控件里将Web.config文件的内容显示出来。在页面的后台类里添加如下的代码,该代码添加了一个名为DisplayWebConfig的方法,在Page_Load事件处理器里,当Page.IsPostBack
为 false时便调用该方法:

privatevoid ProtectSection(string sectionName, string provider)
{
 Configuration config = WebConfigurationManager.
 OpenWebConfiguration(Request.ApplicationPath);
 ConfigurationSection section = config.GetSection(sectionName);
 if (section != null &&!section.SectionInformation.IsProtected)
 {
  section.SectionInformation.ProtectSection(provider);
  config.Save();
 }
}
private void UnProtectSection(string sectionName) {
 Configuration config =WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
 ConfigurationSection section = config.GetSectio n(sectionName);
 if (section != null && section.SectionInformation.IsProtected)
 {
  section.SectionInformation.UnprotectSection();
  config.Save();
 }
  你可以从一个ASP.NET页面中调用这个ProtectSection(sectionName,provider)方法,其相应的参数是一个节名(如connectionStrings)和一个提供程序(如DataProtectionConfigurationProvider),并且它打开Web.config文件,引用该节,调用SectionInformation对象的ProtectSection(provider)方法,最后保存配置变化。

protected void Page_Load(object sender, EventArgs e)
{
 // On the first page visit, call DisplayWebConfig method
 if (!Page.IsPostBack)
 DisplayWebConfig();
}

private void DisplayWebConfig()
{
 // Reads in the contents of Web.config and displays them in the TextBox
 StreamReader webConfigStream =
 File.OpenText(Path.Combine(Request.PhysicalApplicationPath, "Web.config"));
 string configContents = webConfigStream.ReadToEnd();
 webConfigStream.Close();

 WebConfigContents.Text = configContents;
}

  另一方面,UnProtectSection(provider)方法实现解密一个特定的配置节。在此,仅需要传入要解密的节-我们不需要麻烦提供程序,因为该信息已经存储在伴随encrypted节的标记中(也即是,在上面的示例中的<connectionStrings>节,在被加密以后,它包含了提供程序:<connectionStringsconfigProtectionProvider=”DataProtectionConfigurationProvider”>)。

  该DisplayWebConfig方法调用File
class类来打开应用程序的Web.config文件;调用StreamReader
class类将内容读入一个字符串;再调用Path
class类来获取Web.config文件的物理地址.这3个类都位于System.IO命名空间.所以我们应该在后台类的顶部添加using
System.IO声明,又或者在这些类的前面添加“System.IO.”前缀.

  记住,一旦该数据被加密,当从一个ASP.NET页面读取它时(也即是,从一个SqlDataSource控件或以编程方式经由ConfigurationManager.ConnectionStrings[connStringName].ConnectionString读取该连接字符串信息),ASP.NET会自动地解密该连接字符串并且返回普通文本值。换句话说,在实现加密后,你一点不需要改变你的代码。相当酷,对不对?

  接下来,我们需要为这2个按钮的Click事件添加事件处理器,在一个DPAPI
provider里使用机器级密匙对<connectionStrings>节点进行加密和解密.在设计器里,双击这2个按钮以添加Click事件处理器,添加如下代码:

  从本文下载的示例ASP.NET 2.0网站中,你会发现有一个示例页面,它展示了该站点的Web.config文件,其中有一个多行TextBox,还提供了相应的Web控件按钮用于加密配置文件的各个部分。这个示例中也使用了上面已经讨论过的ProtectSection()和UnProtectSection()方法。

protected void EncryptConnStrings_Click(object sender, EventArgs e)
{
 // Get configuration information about Web.config
 Configuration config =
 WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

 // Let's work with the <connectionStrings> section
 ConfigurationSection connectionStrings = config.GetSection("connectionStrings");
 if (connectionStrings != null)
 // Only encrypt the section if it is not already protected
 if (!connectionStrings.SectionInformation.IsProtected)
 {
  // Encrypt the <connectionStrings> section using the
  // DataProtectionConfigurationProvider provider
  connectionStrings.SectionInformation.ProtectSection(
  "DataProtectionConfigurationProvider");
  config.Save();

  // Refresh the Web.config display
  DisplayWebConfig();
 }
}

protected void DecryptConnStrings_Click(object sender, EventArgs e)
{
 // Get configuration information about Web.config
 Configuration config =
 WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

 // Let's work with the <connectionStrings> section
 ConfigurationSection connectionStrings =
 config.GetSection("connectionStrings");
 if (connectionStrings != null)
 // Only decrypt the section if it is protected
 if (connectionStrings.SectionInformation.IsProtected)
 {
  // Decrypt the <connectionStrings> section
  connectionStrings.SectionInformation.UnprotectSection();
  config.Save();

  // Refresh the Web.config display
  DisplayWebConfig();
 }
}

  六、 使用命令行工具aspnet_regiis.exe

  这2个按钮的事件处理器的代码几乎是一样的.它们一开始都通过WebConfigurationManager
class类的OpenWebConfiguration方法获取当前应用程序的Web.config文件的信息.
该方法根据指定的有效路径返回web配置文件。接下来,再通过Configuration
class类的GetSection(sectionName)方法访问Web.config文件的<connectionStrings>节点.该方法返回一个ConfigurationSection对象.

  你还能够使用aspnet_regiis.exe命令行工具来加密和解密Web.config文件配置部分,你可以在”%WINDOWSDIR%\Microsoft.Net\Framework\version”目录下找到这个工具。为了加密Web.config文件中的一个节,你可以在这个命令行工具中使用DPAPI机器密钥,如下所示:

  该ConfigurationSection对象包含了一个SectionInformation属性,用来阐述加密节点的其它相关信息.
就像上面的代码显示的那样,我们通过查看SectionInformation的IsProtected属性来判断是否对配置节点进行了加密.此外,还可以通过SectionInformation的ProtectSection(provider)
和 UnprotectSection方法对节点进行加密或解密.

  加密一个特定网站的Web.config文件的通用形式:

  ProtectSection(provider)方法有一个字符串类型的输入参数,该参数指定了用来加密的protected
configuration
provider的名称。在EncryptConnString按钮的事件处理器里,我们将“DataProtectionConfigurationProvider”传递给ProtectSection(provider)方法,因此指明了用到的是DPAPI
provider.而UnprotectSection方法可以确定加密时用到的provider,因此不需要任何的输入参数.

aspnet_regiis.exe -pef section physical_directory -prov provider
  或:

  调用ProtectSection(provider) 或
UnprotectSection方法后,我还必须调用Configuration对象的Save
method方法来进行具体的操作.
一旦完成加密或解密并保存后,我们调用DisplayWebConfig方法将更新后的Web.config文件的内容上传到TextBox控件.

aspnet_regiis.exe -pe section -app virtual_directory -prov provider
  加密一个特定网站的Web.config文件的具体实例:

  键入上述代码后,在浏览器里测试EncryptingConfigSections.aspx页面,最开始你将看到页面将Web.config文件的<connectionStrings>节点的内容以纯文本的形式展示出来.

aspnet_regiis.exe -pef “connectionStrings” “C:\Inetpub\wwwroot\MySite” -prov “DataProtectionConfigurationProvider”
  或:

图片 3
图3:显示<connectionStrings>节点的内容

aspnet_regiis.exe -pe “connectionStrings” -app “/MySite” -prov “DataProtectionConfigurationProvider”
  解密一个特定网站的Web.config文件的通用形式:

  现在,点击“Encrypt Connection Strings”按钮,如果“请求确认”(request
validation)处于激活状态的话,回传页面时将抛出一个HttpRequestValidationException异常,显示一个消息:“A
potentially dangerous Request.Form value was detected from the
client.”。这个Request validation,在ASP.NET
2.0里默认为处于激活状态,禁止服务器接受含有未编码的HTML的内容,它被设计来保护服务器免受注入式脚本的攻击.可以从页面或应用程序来禁止该功能.我们在该页禁用它,在页面声明代码的顶部的的@Page标记里ValidateRequest设置为false,如下:

aspnet_regiis.exe -pdf section physical_directory
  或:

<%@ Page ValidateRequest="False" ... %>

aspnet_regiis.exe -pd section -app virtual_directory 
  解密一个特定网站的Web.config文件的具体实例:

  在禁用该功能后,再次点击“Encrypt Connection
Strings”按钮,页面回传后就可以访问配置文件了,并用DPAPI
provider对<connectionStrings>节点进行加密.
TextBox控件然后将Web.config文件更新后的内容显示出来,如图4所示,<connectionStrings>节点的信息现在已经被加密了.

aspnet_regiis.exe -pdf “connectionStrings” “C:\Inetpub\wwwroot\MySite”
  或:

图片 4
图4:点击“Encrypt Connection
Strings”按钮对<connectionString>节点进行加密

  你还能够指定由aspnet_regiis.exe来执行machine.config文件的加密/解密。

在加密前,我暂时地将<CipherData>元素里的内容转移了:

  【提示】 加密ASP.NET版本1.x中的配置设置

<connectionStrings
 configProtectionProvider="DataProtectionConfigurationProvider">
 <EncryptedData>
 <CipherData>
 <CipherValue>AQAAANCMnd8BFdERjHoAwE/...zChw==</CipherValue>
 </CipherData>
 </EncryptedData>
</connectionStrings>

  为了保护ASP.NET版本1.x中的配置设置,开发者需要加密并把敏感的设置存储在web服务器的注册表中,并以一种”强”键方式存储。配置文件中不是存储加密的内容(如ASP.NET 2.0那样),而只是包含一个到存储该加密值的注册表键的引用。例如:

  注意:<connectionStrings>元素指定了用来加密的provider(即DataProtectionConfigurationProvider).当点击“Decrypt
Connection
Strings”按钮时UnprotectSection方法将会用到该信息.对于加密的连接字符串,系统可以自动的对其解密.简而言之,我们不需要再对加密的<connectionString>节点添加任何其它的代码。我们来做个验证,打开以前的教程,比如(~/BasicReporting/SimpleDisplay.aspx页面),如图5所示,页面像我们期望的那样工作正常,这就表明了经过加密的连接字符串被ASP.NET页面自动解密了.

<identity impersonate=”true”
userName=”registry:HKLM\SOFTWARE\MY_SECURE_APP\identity\ASPNET_SETREG,userName”
password=”registry:HKLM\SOFTWARE\MY_SECURE_APP\identity\ASPNET_SETREG,password” />
  微软为开发人员提供了aspnet_setreg.exe命令行工具,用于加密敏感的配置信息并且把它移动到一个”强”注册表入口处。遗憾的是,这个工具仅针对特定的配置设置工作;相比之下,ASP.NET 2.0允许加密任何配置节。

图片 5
图5:数据访问层自动解密连接字符串信息

  有关于在一个ASP.NET 1.x应用程序中使用aspnet_setreg.exe的更多信息请参考MSDN中的KB#32990。遗憾的是,这个命令行程序仅能加密配置设置中的预定义的节,并且不允许你加密你自己添加的数据库连接字符串和其它敏感信息。

  为将加密的<connectionStrings>节点恢复到纯文本样式,点击“Decrypt
Connection
Strings”按钮。页面回传后,你将看到Web.config文件里的连接字符串恢复到纯文本样式.此时,屏幕开起来像是最初登录的样子(见图3)

  七、 结论

第三步:用aspnet_regiis.exe对配置节点进行加密

  在本文中,我们学习了如何使用ASP.NET 2.0提供的不同的加密选项来保护配置节信息,还讨论了如何使用编程技术和aspnet_regiis.exe来分别加密Web.config中的配置节。保护你的敏感的配置设置有助于确保你的站点更难于被黑客攻击-通过使其更难于发现敏感的配置设置。如今,ASP.NET 2.0已经提供了相对容易的加密和解密技术,开发者毫无理由不使用这种方式来保护你的敏感的配置设置。

  .NET
Framework包含了很多的命令行工具,可以在$WINDOWS$/Microsoft.NET/Framework/version/
folder文件夹里找到这些工具.以第59章《使用SQL缓存依赖项SqlCacheDependency》为例,我们用aspnet_regsql.exe命令行工具为SQL缓存依赖添加里必要的体系结构.该文件夹里的另一个有用的工具是ASP.NET
IIS Registration tool (aspnet_regiis.exe).
就像其名字暗示的那样,这个ASP.NET IIS
Registration工具主要用来在微软专业Web server,IIS上注册ASP.NET
2.0应用程序.

  除了其与IIS相关的属性外,该ASP.NET IIS
Registration工具也可以对Web.config文件的配置节点进行加密和解密.
下面的是使用aspnet_regiis.exe命令行工具对配置节点加密的常规代码:

aspnet_regiis.exe -pef section physical_directory -prov provider

  其中section是要加密的配置节点(比如“connectionStrings”);physical_directory
为web应用程序根节点的完整物理路径;provider是用到的protected
configuration provider的名称(比如“DataProtectionConfigurationProvider”).
另外,如果你将web应用程序在IIS里进行了注册了的话,你就可以用相当路径来代替绝对路径:

aspnet_regiis.exe -pe section -app virtual_directory -prov provider

  下面为使用aspnet_regiis.exe的例子,它用DPAPI
provider,机器级密匙,对<connectionStrings>节点进行加密:

aspnet_regiis.exe -pef
“connectionStrings” “C:/Websites/ASPNET_Data_Tutorial_73_CS”
-prov “DataProtectionConfigurationProvider”

  类似的,该aspnet_regiis.exe命令行工具也可以用来解密配置节点,不过我们要将-pef替换成-pdf或-pd。当然,解密时不需要指定provider名称.

aspnet_regiis.exe -pdf section physical_directory
 -- or --
aspnet_regiis.exe -pd section -app virtual_directory

  注意:由于我们使用的是DPAPI
provider,它使用的密匙是又电脑指定的,所以你必须在存储web页面的同一台电脑上运行aspnet_regiis.exe工具.
比如,你在本地电脑上运行这个命令行,然后又将加了密的连接字符串上载到另一个服务器上,该服务器就无法对其进行解密,因为加密的密匙是在本地电脑上指定的.如果是使用RSA
provider的话就不存在这种局限性,因为RSA provider可以将密匙(RSA
keys)传递给另一台电脑.

理解Database Authentication Options

  在任何应用程序向Microsoft SQL
Server数据库发出SELECT,INSERT,UPDATE,或DELETE请求之前,数据库首先要确定请求者的身份.该过程可分为2种验证模式:authentication
和 SQL Server provides:

.Windows Authentication:在Visual Studio 2005的ASP.NET Development
Server里运行一个ASP.NET应用程序时,ASP.NET应用程序假定身份(identity)为当前登录用户。而如果运行在Microsoft
Internet Information Server
(IIS)上的话,ASP.NET应用程序假定身份(identity)为domainName/MachineName
or domainName/NETWORK SERVICE,,虽然这些都可以用户定制.

.SQL Authentication:验证的时候需要提供用户ID和password,使用SQL
authentication的话,可以由连接字符串来提供ID和password.

  一般使用Windows authentication模式,因为其更安全.在Windows
authentication模式下,连接字符串不需要用户名和密码,并且如果web服务器和数据库服务器分属不同的电脑的话,(credentials)认证在网络间传输时并不以纯文本格式传输.而如果是SQL
authentication模式的话,将对连接字符串进行硬编码,且认证在web服务器和数据库服务器之间以纯文本格式进行传输.

  本教程使用的是Windows
authentication.我们可以通过连接字符串来查看到底使用的是哪种认证。本教程的Web.config文件的连接字符串如下:

Data Source=./SQLEXPRESS; AttachDbFilename=|DataDirectory|/NORTHWND.MDF;
Integrated Security=True; User Instance=True

  术语“Integrated
Security=True”,以及缺少用户名和密码都表明我们使用的是Windows
authentication模式。不过在一些连接字符串里用术语“Trusted Connection=Yes”
或 “Integrated Security=SSPI”来替换“Integrated Security=True”,
不过它们都表明使用的是Windows authentication.

下面的代码显示使用的是SQL authentication:

Server=serverName; Database=Northwind; uid=userID; pwd=password

  假想某个攻击者可以查看你的应用程序的Web.config文件。如果你使用的是SQL
authentication模式通过Internet连接到数据库,攻击者可以利用连接字符串通过SQL
Management
Studio或他自己网站上的ASP.NET页面连接到你的数据库.为降低风险,我们需要对Web.config文件的连接字符串进行加密.

  注意:关于SQL
Server里不同认证模式的更多信息应参阅文章《Building Secure ASP.NET
Applications: Authentication, Authorization, and Secure
Communication》(http://msdn2.microsoft.com/en-us/library/aa302392.aspx);关于Windows 和 SQL
authentication不同之处的更多示例,应参阅ConnectionStrings.com网站.

结语:

  默认情况下,ASP.NET应用程序里的所有以.config为后缀的文件都不能通过浏览器访问.这是因为这些文件可能包含了一些敏感信息,比如:数据库连接字符串、用户名和密码等。
.NET
2.0包含的保护配置系统可以通过对指定的配置节点进行加密来加以保护.有2种内置的protected
configuration providers:一个使用RSA运算法则,而另一个使用Windows Data
Protection API (DPAPI).

  本文考察了使用DPAPI
provider来对配置信息进行加密和解密.我们可以通过编程的方式,就像在第2步探讨的那样;也可以通过使用aspnet_regiis.exe命令行工具,就像在第3步探讨的那样。关于使用RSA
provider及用户级密匙的更多信息请参考本文的外延阅读.

  祝编程快乐!

作者简介

  本系列教程作者 Scott
Mitchell,著有六本ASP/ASP.NET方面的书,是4GuysFromRolla.com的创始人,自1998年以来一直应用
微软Web技术。大家可以点击查看全部教程《[翻译]Scott Mitchell 的ASP.NET
2.0数据教程》,希望对大家的学习ASP.NET有所帮助。

您可能感兴趣的文章:

  • ASP.NET Core 数据保护(Data
    Protection)上篇
  • Oracle数据库
    DGbroker三种保护模式的切换
  • C++多线程编程时的数据保护
  • 探究在C++程序并发时保护共享数据的问题
  • 利用DOS命令来对抗U盘病毒保护U盘数据
  • 利用MySQL加密函数保护Web网站敏感数据的方法分享
  • 设置密码保护的SqlServer数据库备份文件与恢复文件的方法
  • 如何保护MySQL中重要数据的方法
  • 保护你的Sqlite数据库(SQLite数据库安全秘籍)
  • ASP.NET Core 数据保护(Data Protection
    集群场景)下篇

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注