当前位置导航:炫浪网>>网络学院>>网页制作>>ASP.NET教程

在 ASP.NET 2.0 中保护机密数据

欢迎进入.NET社区论坛,与200万技术人员互动交流 >>进入

  在配置系统中安全地存储数据是一个难以解决的问题。早年,当我在 ASP.NET 团队的时候,这一特定功能(安全地存储连接字符串)好像不会得到实现了。它被无数个问题(如密钥存储)团团包围,阻碍了解决之路。幸运的是,这个问题不但最终得到了解决,而且还融入到 ASP.NET 2.0 强大的最新 API 组合中,从而使您得以通过编程方式管理 ASP.NET 配置文件。

  不过,在深入探究 ASP.NET 2.0 之前,让我们先研究一下这个问题,了解一下 ASP.NET 1.x 中的各种解决方案。只要您用过 ASP.NET,那么,您无疑会理解在 web.config 文件中存储共享设置的好处。例如,您不必在每次创建新数据库连接时都指定连接字符串,而是可以将该字符串存储在 ASP.NET 配置文件的 <appSettings /> 节中。这样就可以通过 ConfigurationSettings.AppSettings 属性访问连接字符串。下面是一个 <appSettings/> 节的示例:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ConnectionString"
value="server=.;database=demo;uid=db;pwd=*u%a" />
</appSettings>
</configuration>

  这样,每当您需要更改连接字符串时,只需打开该文件,执行更改,即告完成。

  从传统 ASP 转向 ASP.NET 的许多开发人员都对此功能深有体会,因为大多数全局值都是以应用程序变量的形式存储的。实际上,对于 ASP.NET 1.x,在 <appSettings/> 中存储连接字符串是一种推荐的做法。还有一点也值得注意,就是您也可以在 <appSettings/> 中存储其他常用数据,包括 LDAP 路径、常用应用程序设置以及应用程序所需要的其他数据。<appSettings/> 的目标是简化自定义配置节处理程序的编写,这是一项与 ASP.NET 配置系统交互的更高级的技术。自定义配置节处理程序允许您在配置系统内创作和处理自己的 XML 节。

  您也许已经注意到,在 <appSettings/> 中存储的内容没有加密,而是以纯文本的形式存储。<sessionState/> 节也是如此,该节支持在进程外存储 Session 数据。一种备选的存储方式是使用 SQL Server?,并在 <sessionState/> 配置位置中以纯文本形式存储凭据。

  等一等,您不能这样做

  在 <appSettings/> 中存储连接字符串的缺点是不能保证安全性,因为该文件没有经过加密,也没有经过编译。并不是说编译配置信息就会对增强安全性有所帮助;DVD 制造商使用基于密钥的加密方法来保护知识产权,方法是简单地让 DVD 播放器软件供应商将解密密钥存储在他们的编译代码中。某些黑客编写的一小段代码会轻而易举地找到解密密钥。我们常常会在个人网络日志中看到这样的帖子,有人想弄清某种东西在 Microsoft? .NET Framework 中的工作机理,这时就会有人建议:“试试 Reflector.”

  ASP.NET 1.1 — 更好地保守秘密

  在 ASP.NET 1.0 中,如果没有额外的自定义代码,则无法在配置文件中安全地存储连接字符串。ASP.NET 团队在 ASP.NET 1.1 中解决了这个问题,方法是对几个配置条目启用加密。该解决方案是通过 Windows 数据保护 API (DPAPI) 完成的,从而能够加密下列配置条目:

  <identity/> 用来存储 ASP.NET 辅助进程的 Windows? 标识以供模拟之用。

  <processModel/> 用来控制在其下执行 ASP.NET 辅助进程的 Windows 帐户。IIS 6.0 中不使用(请参阅以下注释)。

  <sessionState/> 具体包含 stateConnectionString 和 sqlConnectionString 属性,用于控制 ASP.NET 对进程外状态服务器的验证方式。

  需要注意的很重要的一点是,IIS 6.0(Windows Server? 2003 附带的 Web 服务器)提供了它自己的辅助进程管理子系统,而 ASP.NET 会顺从该系统。因此,ASP.NET 在由 IIS 6.0 托管时,配置系统中的有些辅助进程设置将不被使用。

  随 ASP.NET 1.1 提供了名为 aspnet_setreg.exe 的工具,用以加密配置文件中的数据并将解密密钥存储在 Windows 注册表项中。得到的注册表项具有一个访问控制列表 (ACL),该列表配置为限制有权访问该密钥的 Windows 帐户。“知识库”文章 Q329290“如何使用 ASP.NET 实用工具加密凭据和会话状态连接字符串”中详细介绍了这项技术。

  不过,这个解决方案也有一些缺点。它破坏了 ASP.NET 团队所钟爱的 xcopy 部署,该功能允许在无需访问服务器的情况下部署 ASP.NET 应用程序。运用上文提到的技术,开发人员或系统管理员必须具有本地计算机的访问权限,才能运行命令行工具,进而加密配置数据并将密钥存储在注册表中。

  ASP.NET 2.0 秘密s

  接下来我们可以开始讨论该团队为s在 ASP.NET 2.0 中解决这一问题而做的所有工作了。这次又有一个用于管理配置数据加密的命令行工具:aspnet_regiis.exe.Aspnet_regiis.exe 存在于 ASP.NET 的早期版本中,主要用于手动向 IIS 注册 ASP.NET.例如,使用它向 IIS 添加 aspnet_isapi.dll 以及配置 ASP.NET 应用程序使用的脚本目录。您可在 \Windows\Microsoft.NET\Framework\版本号\ 目录中找到此工具。

欢迎进入.NET社区论坛,与200万技术人员互动交流 >>进入

  使用 aspnet_regiis.exe 加密配置节的过程同它所生成的结果一样扑朔迷离!请看图 1 中 aspnet_regiis.exe /help 的执行结果,您就明白我的意思了。

       

  正如您所看到的那样,除非您非常熟悉安全术语,否则您很快就会被大量的选项和各种设置弄的眼花缭乱。不幸的是,虽然功能强大,但各种工具十分混乱。现在我们暂不研究 aspnet_regiis.exe 的使用方法,先来看一个 ASP.NET 示例页面,该页面使用新的配置 API 来实现配置节的加密。此页面,即 ConnectionEncryption.aspx(可以从 MSDN?Magazine 网站上获得),包含一个 GridView,用所有配置节的列表填充。如图 2 所示。

       

  在研究 ConnectionEncryption.aspx 内部的工作方式之前,先看看这个页面的结果。但是先提出一个警告:使用本工具要求托管 ASP.NET 的进程对当前应用程序的 web.config 文件具有写入权限。默认情况下,IIS 中运行的 ASP.NET 应用程序没有必要的权限。不过,托管在 ASP.NET Development Web Server 中的应用程序使用已登录用户的权限集运行。您在此处看到的该工具的所有用法都是在 ASP.NET Development Web Server 中显示的。建议您在全面了解更改 IIS 权限设置所带来的影响的情况下再执行更改。

  下面是 web.config 中用于存储连接字符串的全新 <connectionStrings> 节的示例条目。<connectionStrings> 节与 <appSettings> 节几乎相同,目前建议在前者中存储连接字符串数据,因为有新的 API 可以专门处理散布在 ASP.NET 中的连接字符串:

<connectionStrings>
<add name="Northwind" providerName="System.Data.SqlClient"
connectionString="Server=localhost;Integrated
Security=True;Database=Northwind" />
</connectionStrings>

  请注意,在这种情况下,仍然使用 Windows 验证连接到数据库。

  单击 ConnectionEncryption.aspx 中的 Encrypt(加密)链接,将 web.config 中连接字符串的值更改为如图3 中所示的内容。加密后,ConnectionEncryption.aspx 页面会将该条目的状态报告为已加密(链接会更改为“Decrypt”(解密),正如您在下图中所见)。

      

  既然页面已经生效,让我们来看一下代码。请看 ConnectionEncryption.aspx.cs 中的第 18 行,在 Page_Load 中,当新的 ASP.NET 2.0 WebConfigurationManager 类检索到本地路径的 Configuration 类的实例时,即填充 GridView:

  Configuration config =

  WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

相关内容
赞助商链接