技术开发 频道

在ASP.NET2.0中保护机密数据

    在研究 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”(解密),正如您在图 4 中所见)。图 4 新页面

 

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

    使用从配置变量中检索到的数据填充数组列表,然后将其绑定到 GridView。源中的大多数其他方法(请参阅下载的代码)用于与实际数据绑定操作有关的业务逻辑规则,如确定节的范围和状态(加密或取消加密)。当单击 Encrypt(加密)或 Decrypt(解密)链接时,GridView1_RowCommand 事件中便会发生神奇的事情。当 GridViewCommandEvent.CommandName 的值为“Encrypt”(加密)时,执行以下代码:

section.SectionInformation.ProtectSection( "DataProtectionConfigurationProvider"); config.Save();

    当 GridViewCommandEvent.CommandName 的值为“Decrypt”(解密)时,则执行以下代码:

section.SectionInformation.UnprotectSection(); config.Save();

    这样,就将加密和解密数据的实际工作转交给了提供程序。一个内置提供程序是 DataProtectionConfigurationProvider。它使用内置的 DPAPI 来存储安全数据,这与 ASP.NET 命令行工具所使用的相同。

    您应该注意,加密数据时,可以指定提供程序,但解密时,却不需要指定提供程序(如果为 ProtectSection 提供的是 null 或空字符串,则将使用在配置文件的 configProtectedData 节中指定的默认提供程序)。这是因为 API 将另一条目写入了配置文件中,该条目用于指定所使用的加密保护提供程序:

<connectionStrings configProtectionProvider= "DataProtectionConfigurationProvider"> <EncryptedData>...</EncryptedData> </connectionStrings>

    此配置条目不仅供 API 用以确定如何解密各个节,而且在 ASP.NET 需要将值(如连接字符串)读入内存但必须先加以解密时,供 ASP.NET 在内部使用。

    ASP.NET 2.0 的新增加密功能的一大优点是,您不但可以加密许多内置配置节,还可以编写自定义的加密提供程序!提供程序是 ASP.NET 2.0 中一个令人惊叹的新扩展模型,它使得开发人员能够实现他们自己的核心功能,如成员身份、个性化等等。此外,鉴于“配置加密”的实现方式,自定义配置节也可以轻松得到加密,因而,对数据的保护不会象 ASP.NET 1.1 中那样,仅仅局限于少数配置节。 

    说点更高明的秘密

    关于加密机密数据的专栏如果不提出几条警告,就不算是完整的专栏。首先,如果能避免保密,就尽量避免保密。如果您使用的是 SQL Server,而且不想在配置系统中存储敏感的连接字符串信息,则使用 SQL Server 附带的集成验证。Windows 验证用于应用服务器与数据库之间的连接。利用此技术,与 SQL Server 之间的连接会直接通过 Windows 进行验证和授权。使用 Windows 验证时,SQL Server 会向验证服务器(无论本地还是远程的)请求令牌,该令牌包含用户的安全标识符 (SID) 及其他信息,然后将这些信息与 SQL Server 所维护的列表进行比较,确定是准许还是拒绝访问。配置文件中不存储密码或用户名。

    另外一件需要切记的事情是,仅仅安全存储了配置文件中的数据并非意味着您可以逃开各种各样的攻击。任何称职(安全双关语)的攻击者,只要他获得了访问您的服务器上的 web.config 文件的足够权限,都可能会对您造成巨大危害。获得系统访问权限、能够处理 web.config 的攻击者可以执行其他操作来操纵数据库,而无需知道连接字符串是什么。因此,安全存储您的连接字符串或其他应用程序数据只是防线之一。另外一项有效防御措施是,使用存储过程并且对那些有权访问您的数据库的帐户设置更加严密的控制。例如,如果存在 SQL 注入漏洞,加密的连接字符串将毫无价值(有关 SQL 注入攻击的详细信息,请参阅 msdn.microsoft.com/msdnmag/issues/04/09/SQLInjection)。

    我曾构建并运行过很多高访问量的网站(如 http://www.asp.net/),因此我受到攻击的机率并不比常人更低。一个常见的特征是攻击常常与最初的漏洞毫无关系。攻击者不会通过最初漏洞攻击,而是会努力保护通过最初的漏洞而制造的后门。 

    结束语
    虽然 ASP.NET 的任一版本都可以保护 ASP.NET 应用程序中的机密数据,但这在 ASP.NET 1.1 中较容易实现,而在 ASP.NET 2.0 中更是轻而易举。使用 ASP.NET 2.0,配置加密不再是亡羊补牢,它已经内置于新的配置 API 之中。使用 ASP.NET 2.0,您不但可以使用 aspnet_regiis.exe 工具来加密配置节,还可以编写您自己的自定义代码(以及自定义提供程序,如果需要)来加密和解密配置数据。

0
相关文章