在 ASP.NET 2.0 中保護機密資料

來源:互聯網
上載者:User
在 ASP.NET 2.0 中保護機密資料 發布日期: 2006-6-13 | 更新日期: 2006-6-13

下載本文的代碼:ExtremeASPNET05.exe (118KB)

本頁內容
等一等,您不能這樣做
ASP.NET 1.1 — 更好地保守秘密
ASP.NET 2.0 秘密
說點更高明的秘密
結束語

在配置系統中安全地儲存資料是一個難以解決的問題。早年,當我在 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) (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 秘密

接下來我們可以開始討論該團隊為在 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/版本號碼/ 目錄中找到此工具。

使用 aspnet_regiis.exe 加密配置節的過程同它所產生的結果一樣撲朔迷離!請看圖 1 中 aspnet_regiis.exe /help 的執行結果,您就明白我的意思了。

圖 1 加密配置資料

正如您所看到的那樣,除非您非常熟悉安全術語,否則您很快就會被大量的選項和各種設定弄的眼花繚亂。不幸的是,雖然功能強大,但各種工具十分混亂。幸運的是,Microsoft 模式和實施方案小組編寫了一篇重要而深入的文章,即“How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI”(英文),它會指導您使用 aspnet_regiis.exe。

現在我們暫不研究 aspnet_regiis.exe 的使用方法,先來看一個 ASP.NET 樣本頁面,該頁面使用新的配置 API 來實現配置節的加密。此頁面,即 ConnectionEncryption.aspx(可以從 MSDNMagazine 網站上獲得),包含一個 GridView,用所有配置節的列表填充。 2 所示。

圖 2 使用新的配置 API

在研究 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 或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 工具來加密配置節,還可以編寫您自己的自訂代碼(以及自訂提供者,如果需要)來加密和解密配置資料。

有關在 ASP.NET 1.1 中儲存機密資料的詳細資料,請參閱“Security Considerations for Hosting ASP.NET version 1.1”(英文)。

請將您的疑問和意見通過 xtrmasp@microsoft.com 發送給 Rob。

Rob Howard 是 Telligent Systems 的創始人,他致力於高效能 Web 應用程式、知識管理和協作系統的開發。Rob 曾在 Microsoft 就職,在那裡協助設計 ASP.NET 1.0、1.1 和 2.0 的基礎結構功能。您可以將電子郵件發送到 rhoward@telligentsystems.com 來聯絡 Rob。

本文摘自 2006 年 5 月發行的《MSDN Magazine》。

轉到原英文頁面


返回頁首

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.