您现在的位置是:网站首页> 编程资料编程资料
在ASP.NET 2.0中操作数据之七十一:保护连接字符串及其它设置信息_自学过程_
2023-05-24
279人已围观
简介 在ASP.NET 2.0中操作数据之七十一:保护连接字符串及其它设置信息_自学过程_
导言:
ASP.NET应用程序的设置信息通常都存储在一个名为Web.config的XML文件里。在教程的前面部分我们已经好几次修改过Web.config文件了.比如在第一章,我们创建名为Northwind的数据集时,数据库连接字符串信息自动的添加到Web.config文件的
由于Web.config文件包含了敏感的信息,比如连接字符串.所以确保Web.config文件内容的安全性是很重要的,对未经授权的访问者应隐藏这些敏感信息.默认情况下,对.config后缀名的文件的任何HTTP请求都由ASP.NET引擎来处理,它将返回“This type of page is not served”的信息,如图1所示.这意味着访问者无法通过在其浏览器的地址栏键入‘http://www.YourServer.com/Web.config'来访问你的Web.config文件.

图1:通过浏览器访问Web.config将返回“This type of page is not served”的信息
但是如果某个攻击者找到其它方法来访问你的Web.config文件的内容又怎么办呢?他会做怎样的修改?我们又采取怎样的步骤来保护Web.config文件的这些信息呢?幸运的是,Web.config文件的绝大多数节点并不包含敏感信息.如果攻击者知道你的ASP.NET页面使用的默认的主题的名字又会搞哪些破坏呢?
Web.config文件的某些节点包含了敏感信息,比如:connection strings, user names, passwords, server names, encryption keys等等.我们能在下面的这些节点找到这些信息:
.. . .
在本文我们将考察保护这些敏感信息的技术.就像我们将看到的那样,.NET Framework 2.0版本包含了一个保护配置系统,我们可以使用它很容易地对选定的配置节点进行加密和解密.
注意:在本文结尾部分,我们将看到微软对从一个ASP.NET应用程序连接到数据库时的建议.除了对连接字符串进行加密外,我们还可以连接到一个处于“安全模式”的数据库使你的系统更强大.
第一步:考察ASP.NET 2.0的保护配置选项
ASP.NET 2.0包含一个保护配置系统以对配置信息进行加密和解密.这些方法包含在.NET Framework,可用来编程加密和解密配置信息.该保护配置系统使用provider model模式.它允许开发者选择执行哪种加密.
.NET Framework包含了2种protected configuration providers:
.RSAProtectedConfigurationProvider :加密和解密时使用不对称RSA运算法则(RSA algorithm)
.DPAPIProtectedConfigurationProvider:加密和解密时使用Windows Data Protection API (DPAPI)
由于保护配置系统执行的是provider design模式,因此我们可以创建自己的protected configuration provider并运用到自己的程序里.具体过程可参阅文章《Implementing a Protected Configuration Provider》(http://msdn2.microsoft.com/en-us/library/wfc2t3az(VS.80).aspx)
RSA providers 和 DPAPI providers在加密和解密时使用“密匙”(keys),这些“密匙”可以存储在“机器级”(Machine-level)和“用户级”(user-level).机器级密匙在这种情况下很理想:每个web应用程序都运行在自己专有的服务器上,或某个服务器上的多个应用程序共享同样的加密信息.而用户级密匙在共享服务器环境里是比较理想的安全选择.此时,同服务器上的其它程序不能对你加密的配置信息进行解密.
本教程的示例将使用DPAPI provider和机器级密匙.具体来说,我们将对Web.config文件里的
注意:RSAProtectedConfigurationProvider 和DPAPIProtectedConfigurationProvider providers在machine.config文件里被分别组册成RsaProtectedConfigurationProvider 和DataProtectionConfigurationProvider。当我们对配置信息进行加密或解密时我们需要提供相应的provider名称(即RsaProtectedConfigurationProvider 或 DataProtectionConfigurationProvider);而不是实际的类型名(即RSAProtectedConfigurationProvider 和 DPAPIProtectedConfigurationProvider). 你可以在$WINDOWS$/Microsoft.NET/Framework/version/CONFIG文件夹里找到machine.config文件.
第二步:通过编程加密和解密配置节点
使用某个provider,我们只需要很少的几行代码就可以对某个配置节点加密或解密.这些代码仅仅需要引用相应的配置节点,调用其ProtectSection 或 UnprotectSection方法,再调用Save方法来执行.另外,.NET Framework包含了一个很有用的命令行功能来进行加密和解密,我们将在第3步考察该功能.
为了便于演示,我们需要创建一个包含按钮的ASP.NET页面,以便于对Web.config文件的
打开AdvancedDAL文件夹里的EncryptingConfigSections.aspx页面,拖一个TextBox控件到页面,设其ID为WebConfigContents;TextMode属性为MultiLine;Width和Rows属性分别为95% 和 15.该TextBox控件用于显示Web.config文件的内容,以查看其内容是否已经加密了.当然,在现实程序里,我们不可能将Web.config文件的内容显示出来.
在该TextBox控件下面添加2个Button控件,ID分别为EncryptConnStrings 和 DecryptConnStrings;设其Text属性为“Encrypt Connection Strings” 和 “Decrypt Connection Strings”.
此时你的界面看起来和下面的差不多:

图2:在页面上添加一个TextBox控件和2个Button控件
接下来,在页面初次登录时我们需要在ID为WebConfigContents的TextBox控件里将Web.config文件的内容显示出来。在页面的后台类里添加如下的代码,该代码添加了一个名为DisplayWebConfig的方法,在Page_Load事件处理器里,当Page.IsPostBack 为 false时便调用该方法:
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; } 该DisplayWebConfig方法调用File class类来打开应用程序的Web.config文件;调用StreamReader class类将内容读入一个字符串;再调用Path class类来获取Web.config文件的物理地址.这3个类都位于System.IO命名空间.所以我们应该在后台类的顶部添加using System.IO声明,又或者在这些类的前面添加“System.IO.”前缀.
接下来,我们需要为这2个按钮的Click事件添加事件处理器,在一个DPAPI provider里使用机器级密匙对
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 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 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 section ConfigurationSection connectionStrings = config.GetSection("connectionStrings"); if (connectionStrings != null) // Only decrypt the section if it is protected if (connectionStrings.SectionInformation.IsProtected) { // Decrypt the section connectionStrings.SectionInformation.UnprotectSection(); config.Save(); // Refresh the Web.config display DisplayWebConfig(); } } 这2个按钮的事件处理器的代码几乎是一样的.它们一开始都通过WebConfigurationManager class类的OpenWebConfiguration方法获取当前应用程序的Web.config文件的信息. 该方法根据指定的有效路径返回web配置文件。接下来,再通过Configuration class类的GetSection(sectionName)方法访问Web.config文件的
该ConfigurationSection对象包含了一个SectionInformation属性,用来阐述加密节点的其它相关信息. 就像上面的代码显示的那样,我们通过查看SectionInformation的IsProtected属性来判断是否对配置节点进行了加密.此外,还可以通过SectionInformation的ProtectSection(provider) 和 UnprotectSection方法对节点进行加密或解密.
ProtectSection(provider)方法有一个字符串类型的输入参数,该参数指定了用来加密的protected configuration provider的名称。在EncryptConnString按钮的事件处理器里,我们将“DataProtectionConfigurationProvider”传递给ProtectSection(provider)方法,因此指明了用到的是DPAPI provider.而UnprotectSection方法可以确定加密时用到的provider,因此不需要任何的输入参数.
调用ProtectSection(provider) 或 UnprotectSection方法后,我还必须调用Configuration对象的Save method方法来进行具体的操作. 一旦完成加密或解密并保存后,我们调用DisplayWebConfig方法将更新后的Web.config文件的内容上传到TextBox控件.
键入上述代码后,在浏览器里测试EncryptingConfigSections.aspx页面,最开始你将看到页面将Web.config文件的

图3:显示
现在,点击“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,如下:
<%@ Page ValidateRequest="False" ... %>
在禁用该功能后,再次点击“Encrypt Connection Strings”按钮,页面回传后就可以访问配置文件了,并用DPAPI provider对

图4:点击“Encrypt Connection Strings”按钮对
在加密前,我暂时地将
AQAAANCMnd8BFdERjHoAwE/...zChw==
注意:

图5:数据访问层自动解密连接字符串信息
为将加密的
第三步:用aspnet_regiis.exe对配置节点进行加密
.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
相关内容
- 在ASP.NET 2.0中操作数据之七十:配置数据库连接和命令等级设置_自学过程_
- 在ASP.NET 2.0中操作数据之六十九:处理Computed Columns列_自学过程_
- 在ASP.NET 2.0中操作数据之六十八:为DataTable添加额外的列_自学过程_
- 在ASP.NET 2.0中操作数据之六十七:在TableAdapters中使用JOINs_自学过程_
- 在ASP.NET 2.0中操作数据之六十六:在TableAdapters中使用现有的存储过程_自学过程_
- Asp.net中使用文本框的值动态生成控件的方法_实用技巧_
- ASP.NET防范SQL注入式攻击的方法_实用技巧_
- 在C#及.NET框架中使用StringBuilder类操作字符串的技巧_实用技巧_
- 在ASP.NET 2.0中操作数据之六十五:在TableAdapters中创建新的存储过程_自学过程_
- 在ASP.NET 2.0中操作数据之六十四:GridView批量添加数据_自学过程_
