輕鬆加密ASP.NET 2.0 Web程式配置資訊

iDotNetSpace發表於2009-10-22
一、 簡介

  當建立ASP.NET 2.0應用程式時,開發者通常都把敏感的配置資訊儲存在Web.config檔案中。最典型的示例就是資料庫連線字串,但是包括在Web.config檔案中的其它敏感資訊還包括SMTP伺服器連線資訊和使用者憑證資料,等等。儘管預設情況下可以配置ASP.NET以拒絕所有對副檔名為.config的檔案資源的HTTP請求;但是,如果一個黑客能夠存取你的web伺服器的檔案系統的話,那麼,Web.config中的敏感資訊仍然能夠被竊取。例如,也許你不小心允許匿名FTP存取你的網站,這樣以來就允許一個黑客簡單地通過FTP協議下載你的Web.config檔案。

  幸好,通過允許加密Web.config檔案中選擇的部分,例如<connectionStrings>節,或你的應用程式使用的一些定製config節,ASP.NET 2.0有助於緩解這個問題。配置部分能夠很容易地使用編碼或aspnet_regiis.exe(一個命令列程式)預以加密。一旦被加密,Web.config設定即可避開"虎視眈眈"的眼睛。而且,當以程式設計方式從你的ASP.NET頁面中檢索加密的配置設定時,ASP.NET會自動地解密它讀取的加密部分。簡言之,一旦配置資訊被加密,你就不需要在你的應用程式中編寫任何其它程式碼或採取任何進一步的行為來使用該加密資料。

  在本文中,我們將討論如何以程式設計方式加密和解密該配置設定部分,並且分析一下命令列程式aspnet_regiis.exe的使用。然後,我們將評估ASP.NET 2.0提供的加密選項。另外,還會簡短地討論一下如何加密ASP.NET版本1.x中的配置資訊。

  二、 前提

  在我們開始探討如何加密ASP.NET 2.0配置資訊之前,請記住下列幾點:

  1. 所有形式的加密都會包含某種祕密,而當加密和解密資料時都要使用這一祕密。對稱加密演算法在加密和解密一個訊息時使用同一把金鑰,而非對稱加密演算法對於加密和解密卻使用不同的金鑰。無論使用哪種技術,最重要的還是看解密金鑰的安全儲存程度。

  2. ASP.NET 2.0提供的配置加密技術的設計目的在於,力圖阻止能夠以某種方式檢索你的配置檔案的黑客的入侵。其實現思想是,如果在黑客的計算機上有你的Web.config檔案;那麼,他不能破解該加密的部分。然而,當web伺服器上的一個ASP.NET頁面從一個加密的配置檔案請求資訊時,該資料必須被解密才能使用(並且這時不需要你編寫任何程式碼)。因此,如果一個黑客能夠把一個能夠查詢配置檔案並顯示它的結果的ASP.NET web頁面上傳到你的系統,那麼,他就能夠以普通文字方式觀看被加密的設定。(詳細情況請參考本文提供的示例ASP.NET頁面,它展示了加密和解密Web.config檔案中各部分的方法;如你所見,一個ASP.NET頁面能夠存取(並顯示)該加密資料的普通文字形式)

  3. 加密和解密配置資訊需要付出一定的效能代價。因此,通常是僅加密包含敏感資訊的配置部分。比如說,可能不需要加密<compilation>或<authorization>配置部分。

  三、 加密何種資訊

  在我們分析如何加密ASP.NET 2.0配置資訊前,讓我們首先來看一下能夠加密什麼配置資訊。使用.NET框架2.0提供的庫,開發人員能夠加密在Web.config或machine.config檔案中的絕大多數的配置部分。這些配置部分是一些作為<configuration>或<system.web>元素子結點的XML元素。例如,下面的示例Web.config檔案中含有三個配置設定,顯式地定義為:

<connectionStrings>,<compilation>和<authentication>。
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<connectionStrings>
 <add name="MembershipConnectionString" connectionString="connectionString"/>
</connectionStrings>
<system.web>
 <compilation debug="true"/>
 <authentication mode="Forms" />
</system.web>
  這些節中的每一個都可以有選擇地被加密,或者通過程式設計方式或通過aspnet_regiis.exe(一個命令列工具)實現。當被加密時,加密後的文字直接儲存在配置檔案中。例如,如果我們要加密上面的<connectionStrings>節,那麼結果Web.config檔案可能看起來如下所示:(注意:篇幅所限,我們省略了一大塊<CipherValue>)

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
 <CipherData>
  <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAed...GicAlQ==</CipherValue>
 </CipherData>
</EncryptedData>
</connectionStrings>
<system.web>
 <compilation debug="true"/>
 <authentication mode="Forms" />
</system.web>
  另外,存在一些你不能使用這個技術加密的配置部分:

  · <processModel>
  · <runtime>
  · <mscorlib>
  · <startup>
  · <system.runtime.remoting>
  · <configProtectedData>
  · <satelliteassemblies>
  · <cryptographySettings>
  · <cryptoNa垃圾廣告pping>
  · <cryptoClasses>

  為了加密這些配置部分,你必須加密這些值並把它儲存在登錄檔中。存在一個aspnet_setreg.exe命令列工具可以幫助你實現這一過程;我們將在本文後面討論這個工具。

  【提示】Web.Config和Machine.Config之區別:

  Web.config檔案指定針對一個特定的web應用程式的配置設定,並且位於應用程式的根目錄下;而machine.config檔案指定所有的位於該web伺服器上的站點的配置設定,並且位於$WINDOWSDIR$\Microsoft.Net\Framework\Version\CONFIG目錄下。

  四、加密選項

  開發人員可以使用ASP.NET 2.0提供程式模型來保護配置節資訊,這允許任何實現都可以被無縫地插入到該API中。.NET框架2.0中提供了兩個內建的提供程式用於保護配置節資訊:

  · Windows資料保護API(DPAPI)提供程式(DataProtectionConfigurationProvider):這個提供程式使用Windows內建的密碼學技術來加解密配置節。預設情況下,這個提供程式使用本機的金鑰。你還能夠使用使用者金鑰,但是這要求進行一點定製。

  · RSA保護的配置提供程式(RSAProtectedConfigurationProvider):使用RSA公鑰加密來加解密配置節。使用這個提供程式,你需要建立儲存用於加解密配置資訊的公鑰和私鑰的金鑰容器。你能夠在一個多伺服器場所下使用RSA,這隻要建立可輸出的金鑰容器即可。
當然,如果需要的話,你還能夠建立自己的保護設定提供程式。

  在本文中,我們僅討論使用DPAPI提供程式使用機器級金鑰。到目前為止,這是最簡單的方法,因為它不請求建立任何金鑰或金鑰容器。當然,其消極的一面在於:一個加密的配置檔案僅能夠用於首先實現加密的web伺服器上;而且,使用機器金鑰將允許加密的文字能夠被web伺服器上的任何網站所解密。

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

  System.Configuration.SectionInformation類對一個配置節的描述進行了抽象。為了加密一個配置節,只需要簡單地使用SectionInformation類的ProtectSection(提供程式)方法,傳遞你想使用的提供程式的名字來執行加密。為了存取你的應用程式的Web.config檔案中的一個特定的配置節,你可以使用WebConfigurationManager類(在System.Web.Configuration名稱空間中)來引用你的Web.config檔案,然後使用它的GetSection(sectionName)方法返回一個ConfigurationSection例項。最後,你可以經由ConfigurationSection例項的SectionInformation屬性得到一個SectionInformation物件。

  下面,我們通過一個簡單的程式碼示例來說明問題:

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)方法,最後儲存配置變化。

  另一方面,UnProtectSection(provider)方法實現解密一個特定的配置節。在此,僅需要傳入要解密的節-我們不需要麻煩提供程式,因為該資訊已經儲存在伴隨encrypted節的標記中(也即是,在上面的示例中的<connectionStrings>節,在被加密以後,它包含了提供程式:<connectionStringsconfigProtectionProvider="DataProtectionConfigurationProvider">)。

  記住,一旦該資料被加密,當從一個ASP.NET頁面讀取它時(也即是,從一個SqlDataSource控制元件或以程式設計方式經由ConfigurationManager.ConnectionStrings[connStringName].ConnectionString讀取該連線字串資訊),ASP.NET會自動地解密該連線字串並且返回普通文字值。換句話說,在實現加密後,你一點不需要改變你的程式碼。相當酷,對不對?

  從本文下載的示例ASP.NET 2.0網站中,你會發現有一個示例頁面,它展示了該站點的Web.config檔案,其中有一個多行TextBox,還提供了相應的Web控制元件按鈕用於加密配置檔案的各個部分。這個示例中也使用了上面已經討論過的ProtectSection()和UnProtectSection()方法。

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

  你還能夠使用aspnet_regiis.exe命令列工具來加密和解密Web.config檔案配置部分,你可以在"%WINDOWSDIR%\Microsoft.Net\Framework\version"目錄下找到這個工具。為了加密Web.config檔案中的一個節,你可以在這個命令列工具中使用DPAPI機器金鑰,如下所示:

  加密一個特定網站的Web.config檔案的通用形式:

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

aspnet_regiis.exe -pe section -app virtual_directory -prov provider
  加密一個特定網站的Web.config檔案的具體例項:

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

aspnet_regiis.exe -pe "connectionStrings" -app "/MySite" -prov "DataProtectionConfigurationProvider"
  解密一個特定網站的Web.config檔案的通用形式:

aspnet_regiis.exe -pdf section physical_directory
  或:

aspnet_regiis.exe -pd section -app virtual_directory 
  解密一個特定網站的Web.config檔案的具體例項:

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

  你還能夠指定由aspnet_regiis.exe來執行machine.config檔案的加密/解密。

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

  為了保護ASP.NET版本1.x中的配置設定,開發者需要加密並把敏感的設定儲存在web伺服器的登錄檔中,並以一種"強"鍵方式儲存。配置檔案中不是儲存加密的內容(如ASP.NET 2.0那樣),而只是包含一個到儲存該加密值的登錄檔鍵的引用。例如:

<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允許加密任何配置節。

  有關於在一個ASP.NET 1.x應用程式中使用aspnet_setreg.exe的更多資訊請參考MSDN中的KB#32990。遺憾的是,這個命令列程式僅能加密配置設定中的預定義的節,並且不允許你加密你自己新增的資料庫連線字串和其它敏感資訊。

  七、 結論

  在本文中,我們學習瞭如何使用ASP.NET 2.0提供的不同的加密選項來保護配置節資訊,還討論瞭如何使用程式設計技術和aspnet_regiis.exe來分別加密Web.config中的配置節。保護你的敏感的配置設定有助於確保你的站點更難於被黑客攻擊-通過使其更難於發現敏感的配置設定。如今,ASP.NET 2.0已經提供了相對容易的加密和解密技術,開發者毫無理由不使用這種方式來保護你的敏感的配置設定。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-617174/,如需轉載,請註明出處,否則將追究法律責任。

相關文章