輕松加密ASP.NET 2.0 Web程序配置信息

2010-08-28 10:50:09來源:西部e網(wǎng)作者:

  一、 簡介

  當(dāng)創(chuàng)建ASP.NET 2.0應(yīng)用程序時(shí),開發(fā)者通常都把敏感的配置信息存儲在Web.config文件中。最典型的示例就是數(shù)據(jù)庫連接字符串,但是包括在Web.config文件中的其它敏感信息還包括SMTP服務(wù)器連接信息和用戶憑證數(shù)據(jù),等等。盡管默認(rèn)情況下可以配置ASP.NET以拒絕所有對擴(kuò)展名為.config的文件資源的HTTP請求;但是,如果一個(gè)黑客能夠存取你的web服務(wù)器的文件系統(tǒng)的話,那么,Web.config中的敏感信息仍然能夠被竊取。例如,也許你不小心允許匿名FTP存取你的網(wǎng)站,這樣以來就允許一個(gè)黑客簡單地通過FTP協(xié)議下載你的Web.config文件。

  幸好,通過允許加密Web.config文件中選擇的部分,例如<connectionStrings>節(jié),或你的應(yīng)用程序使用的一些定制config節(jié),ASP.NET 2.0有助于緩解這個(gè)問題。配置部分能夠很容易地使用編碼或aspnet_regiis.exe(一個(gè)命令行程序)預(yù)以加密。一旦被加密,Web.config設(shè)置即可避開"虎視眈眈"的眼睛。而且,當(dāng)以編程方式從你的ASP.NET頁面中檢索加密的配置設(shè)置時(shí),ASP.NET會自動(dòng)地解密它讀取的加密部分。簡言之,一旦配置信息被加密,你就不需要在你的應(yīng)用程序中編寫任何其它代碼或采取任何進(jìn)一步的行為來使用該加密數(shù)據(jù)。

  在本文中,我們將討論如何以編程方式加密和解密該配置設(shè)置部分,并且分析一下命令行程序aspnet_regiis.exe的使用。然后,我們將評估ASP.NET 2.0提供的加密選項(xiàng)。另外,還會簡短地討論一下如何加密ASP.NET版本1.x中的配置信息。

  二、 前提

  在我們開始探討如何加密ASP.NET 2.0配置信息之前,請記住下列幾點(diǎn):

  1. 所有形式的加密都會包含某種秘密,而當(dāng)加密和解密數(shù)據(jù)時(shí)都要使用這一秘密。對稱加密算法在加密和解密一個(gè)消息時(shí)使用同一把密鑰,而非對稱加密算法對于加密和解密卻使用不同的密鑰。無論使用哪種技術(shù),最重要的還是看解密密鑰的安全保存程度。

  2. ASP.NET 2.0提供的配置加密技術(shù)的設(shè)計(jì)目的在于,力圖阻止能夠以某種方式檢索你的配置文件的黑客的入侵。其實(shí)現(xiàn)思想是,如果在黑客的計(jì)算機(jī)上有你的Web.config文件;那么,他不能破解該加密的部分。然而,當(dāng)web服務(wù)器上的一個(gè)ASP.NET頁面從一個(gè)加密的配置文件請求信息時(shí),該數(shù)據(jù)必須被解密才能使用(并且這時(shí)不需要你編寫任何代碼)。因此,如果一個(gè)黑客能夠把一個(gè)能夠查詢配置文件并顯示它的結(jié)果的ASP.NET web頁面上傳到你的系統(tǒng),那么,他就能夠以普通文本方式觀看被加密的設(shè)置。(詳細(xì)情況請參考本文提供的示例ASP.NET頁面,它展示了加密和解密Web.config文件中各部分的方法;如你所見,一個(gè)ASP.NET頁面能夠存取(并顯示)該加密數(shù)據(jù)的普通文本形式)

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

  三、 加密何種信息

  在我們分析如何加密ASP.NET 2.0配置信息前,讓我們首先來看一下能夠加密什么配置信息。使用.NET框架2.0提供的庫,開發(fā)人員能夠加密在Web.config或machine.config文件中的絕大多數(shù)的配置部分。這些配置部分是一些作為<configuration>或<system.web>元素子結(jié)點(diǎn)的XML元素。例如,下面的示例Web.config文件中含有三個(gè)配置設(shè)置,顯式地定義為:

<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>
。糲ompilation debug="true"/>
 <authentication mode="Forms" />
</system.web>

  這些節(jié)中的每一個(gè)都可以有選擇地被加密,或者通過編程方式或通過aspnet_regiis.exe(一個(gè)命令行工具)實(shí)現(xiàn)。當(dāng)被加密時(shí),加密后的文本直接存儲在配置文件中。例如,如果我們要加密上面的<connectionStrings>節(jié),那么結(jié)果Web.config文件可能看起來如下所示:(注意:篇幅所限,我們省略了一大塊<CipherValue>)

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
。糃ipherData>
  <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAed...GicAlQ==</CipherValue>
。/CipherData>
</EncryptedData>
</connectionStrings>
<system.web>
 <compilation debug="true"/>
。糰uthentication mode="Forms" />
</system.web>


  另外,存在一些你不能使用這個(gè)技術(shù)加密的配置部分:

  · <processModel>
  · <runtime>
  · <mscorlib>
  · <startup>
  · <system.runtime.remoting>
  · <configProtectedData>
  · <satelliteassemblies>
  · <cryptographySettings>
  · <cryptoNameMapping>
  · <cryptoClasses>

  為了加密這些配置部分,你必須加密這些值并把它存儲在注冊表中。存在一個(gè)aspnet_setreg.exe命令行工具可以幫助你實(shí)現(xiàn)這一過程;我們將在本文后面討論這個(gè)工具。

  【提示】Web.Config和Machine.Config之區(qū)別:

  Web.config文件指定針對一個(gè)特定的web應(yīng)用程序的配置設(shè)置,并且位于應(yīng)用程序的根目錄下;而machine.config文件指定所有的位于該web服務(wù)器上的站點(diǎn)的配置設(shè)置,并且位于$WINDOWSDIR$\Microsoft.Net\Framework\Version\CONFIG目錄下。

  四、加密選項(xiàng)

  開發(fā)人員可以使用ASP.NET 2.0提供程序模型來保護(hù)配置節(jié)信息,這允許任何實(shí)現(xiàn)都可以被無縫地插入到該API中。.NET框架2.0中提供了兩個(gè)內(nèi)置的提供程序用于保護(hù)配置節(jié)信息:

  · Windows數(shù)據(jù)保護(hù)API(DPAPI)提供程序(DataProtectionConfigurationProvider):這個(gè)提供程序使用Windows內(nèi)置的密碼學(xué)技術(shù)來加解密配置節(jié)。默認(rèn)情況下,這個(gè)提供程序使用本機(jī)的密鑰。你還能夠使用用戶密鑰,但是這要求進(jìn)行一點(diǎn)定制。

  · RSA保護(hù)的配置提供程序(RSAProtectedConfigurationProvider):使用RSA公鑰加密來加解密配置節(jié)。使用這個(gè)提供程序,你需要?jiǎng)?chuàng)建存儲用于加解密配置信息的公鑰和私鑰的密鑰容器。你能夠在一個(gè)多服務(wù)器場所下使用RSA,這只要?jiǎng)?chuàng)建可輸出的密鑰容器即可。
當(dāng)然,如果需要的話,你還能夠創(chuàng)建自己的保護(hù)設(shè)置提供程序。

  在本文中,我們僅討論使用DPAPI提供程序使用機(jī)器級密鑰。到目前為止,這是最簡單的方法,因?yàn)樗徽埱髣?chuàng)建任何密鑰或密鑰容器。當(dāng)然,其消極的一面在于:一個(gè)加密的配置文件僅能夠用于首先實(shí)現(xiàn)加密的web服務(wù)器上;而且,使用機(jī)器密鑰將允許加密的文本能夠被web服務(wù)器上的任何網(wǎng)站所解密。

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

  System.Configuration.SectionInformation類對一個(gè)配置節(jié)的描述進(jìn)行了抽象。為了加密一個(gè)配置節(jié),只需要簡單地使用SectionInformation類的ProtectSection(提供程序)方法,傳遞你想使用的提供程序的名字來執(zhí)行加密。為了存取你的應(yīng)用程序的Web.config文件中的一個(gè)特定的配置節(jié),你可以使用WebConfigurationManager類(在System.Web.Configuration命名空間中)來引用你的Web.config文件,然后使用它的GetSection(sectionName)方法返回一個(gè)ConfigurationSection實(shí)例。最后,你可以經(jīng)由ConfigurationSection實(shí)例的SectionInformation屬性得到一個(gè)SectionInformation對象。

  下面,我們通過一個(gè)簡單的代碼示例來說明問題:

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();
 }

  你可以從一個(gè)ASP.NET頁面中調(diào)用這個(gè)ProtectSection(sectionName,provider)方法,其相應(yīng)的參數(shù)是一個(gè)節(jié)名(如connectionStrings)和一個(gè)提供程序(如DataProtectionConfigurationProvider),并且它打開Web.config文件,引用該節(jié),調(diào)用SectionInformation對象的ProtectSection(provider)方法,最后保存配置變化。

  另一方面,UnProtectSection(provider)方法實(shí)現(xiàn)解密一個(gè)特定的配置節(jié)。在此,僅需要傳入要解密的節(jié)-我們不需要麻煩提供程序,因?yàn)樵撔畔⒁呀?jīng)存儲在伴隨encrypted節(jié)的標(biāo)記中(也即是,在上面的示例中的<connectionStrings>節(jié),在被加密以后,它包含了提供程序:<connectionStringsconfigProtectionProvider="DataProtectionConfigurationProvider">)。

  記住,一旦該數(shù)據(jù)被加密,當(dāng)從一個(gè)ASP.NET頁面讀取它時(shí)(也即是,從一個(gè)SqlDataSource控件或以編程方式經(jīng)由ConfigurationManager.ConnectionStrings[connStringName].ConnectionString讀取該連接字符串信息),ASP.NET會自動(dòng)地解密該連接字符串并且返回普通文本值。換句話說,在實(shí)現(xiàn)加密后,你一點(diǎn)不需要改變你的代碼。相當(dāng)酷,對不對?

  從本文下載的示例ASP.NET 2.0網(wǎng)站中,你會發(fā)現(xiàn)有一個(gè)示例頁面,它展示了該站點(diǎn)的Web.config文件,其中有一個(gè)多行TextBox,還提供了相應(yīng)的Web控件按鈕用于加密配置文件的各個(gè)部分。這個(gè)示例中也使用了上面已經(jīng)討論過的ProtectSection()和UnProtectSection()方法。

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

  你還能夠使用aspnet_regiis.exe命令行工具來加密和解密Web.config文件配置部分,你可以在"%WINDOWSDIR%\Microsoft.Net\Framework\version"目錄下找到這個(gè)工具。為了加密Web.config文件中的一個(gè)節(jié),你可以在這個(gè)命令行工具中使用DPAPI機(jī)器密鑰,如下所示:

  加密一個(gè)特定網(wǎng)站的Web.config文件的通用形式:

aspnet_regiis.exe -pef section physical_directory -prov provider

  或:

aspnet_regiis.exe -pe section -app virtual_directory -prov provider

  加密一個(gè)特定網(wǎng)站的Web.config文件的具體實(shí)例:

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

  或:

aspnet_regiis.exe -pe "connectionStrings" -app "/MySite" -prov "DataProtectionConfigurationProvider"

  解密一個(gè)特定網(wǎng)站的Web.config文件的通用形式:

aspnet_regiis.exe -pdf section physical_directory

  或:

aspnet_regiis.exe -pd section -app virtual_directory

  解密一個(gè)特定網(wǎng)站的Web.config文件的具體實(shí)例:

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

  或:

  你還能夠指定由aspnet_regiis.exe來執(zhí)行machine.config文件的加密/解密。

  【提示】 加密ASP.NET版本1.x中的配置設(shè)置

  為了保護(hù)ASP.NET版本1.x中的配置設(shè)置,開發(fā)者需要加密并把敏感的設(shè)置存儲在web服務(wù)器的注冊表中,并以一種"強(qiáng)"鍵方式存儲。配置文件中不是存儲加密的內(nèi)容(如ASP.NET 2.0那樣),而只是包含一個(gè)到存儲該加密值的注冊表鍵的引用。例如:

<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" />

  微軟為開發(fā)人員提供了aspnet_setreg.exe命令行工具,用于加密敏感的配置信息并且把它移動(dòng)到一個(gè)"強(qiáng)"注冊表入口處。遺憾的是,這個(gè)工具僅針對特定的配置設(shè)置工作;相比之下,ASP.NET 2.0允許加密任何配置節(jié)。

  有關(guān)于在一個(gè)ASP.NET 1.x應(yīng)用程序中使用aspnet_setreg.exe的更多信息請參考MSDN中的KB#32990。遺憾的是,這個(gè)命令行程序僅能加密配置設(shè)置中的預(yù)定義的節(jié),并且不允許你加密你自己添加的數(shù)據(jù)庫連接字符串和其它敏感信息。

  七、 結(jié)論

  在本文中,我們學(xué)習(xí)了如何使用ASP.NET 2.0提供的不同的加密選項(xiàng)來保護(hù)配置節(jié)信息,還討論了如何使用編程技術(shù)和aspnet_regiis.exe來分別加密Web.config中的配置節(jié)。保護(hù)你的敏感的配置設(shè)置有助于確保你的站點(diǎn)更難于被黑客攻擊-通過使其更難于發(fā)現(xiàn)敏感的配置設(shè)置。如今,ASP.NET 2.0已經(jīng)提供了相對容易的加密和解密技術(shù),開發(fā)者毫無理由不使用這種方式來保護(hù)你的敏感的配置設(shè)置。

關(guān)鍵詞:ASP.NET

贊助商鏈接: