天天看點

C#基礎:.NET環境下WebConfig的加密

在将ASP.NET項目部署到伺服器上時,内網環境下Web.Config往往是直接複制過去。對于外網環境,則需要對Web.Config檔案進行加密。

.NET環境下一共提供了2種方式的加密功能,分别是DpapiProtectedConfigurationProvider和RsaProtectedConfigurationProvider提供程式。

前者在本機加密Web.Config後,隻能在本機進行解密,如果需要将Config檔案複制到外部主機,則無法進行解密。後者在本機加密Config檔案後,可以到處密鑰容器,當把Config檔案複制到外部主機後,可對先前導出的檔案進行導入功能,導入後既可自動解密。

由于經常需要複制Config檔案到外部主機,是以Rsa保護程式更加适用于實際業務場景,本文将詳細介紹RsaProtectedConfigurationProvider程式的使用步驟。

1. 使用RsaProvider提供程式,需要首先進入.NET Framework運作環境,可以配置環境變量或使用cd指令。

cd  C:\Windows\Microsoft.NET\Framework\v2.0.50727

2. 接着便可以使用aspnet_regiis.exe建立一個Rsa密鑰容器。密鑰容器分使用者級别和計算機級别兩種情況,由于使用使用者級别密鑰沒什麼益處,一般使用計算機級别既可。

aspnet_regiis -pc "MyKeys" -exp

3. 建立密鑰容器後,還需要設定密鑰容器的通路權限,下面的指令授予NETWORK SERVICE 帳戶對計算機級别的 “MyKeys” RSA 密鑰容器的通路權限。msdn上有一個aspx程式會展示你的asp.net程式的使用者标志,不過本人實際執行pa指令後會報錯。

aspnet_regiis -pa "MyKeys" "NT AUTHORITY\NETWORK SERVICE"

4. 在Web.Config檔案中加上如下配置節點,MyProvider為你的保護程式名稱,可随意指定。keyContainerName為前面設定的密鑰容器名稱,useMachineContainer為true表示使用計算機級别密鑰,為false表示使用使用使用者級密鑰。

這段配置節不要像msdn那樣直接放在configure配置節點下面,這樣會報錯,建議放在你需要加密節點的後面。

 5 .下面的指令将對指定路徑下的config檔案節點進行加密,如果配置檔案中還有session的sql連接配接字元串,也可以對sessionState節點進行加密。

aspnet_regiis -pef "connectionStrings"  "D:\WebApp"  -prov   "MyProvider"

aspnet_regiis -pef "system.web/sessionState"  "D:\WebApp"  -prov   "MyProvider"

  加密後的connectionStrings節點如下所示,此時仍可通路ASP.NET應用程式。

 如果需要解密,可以執行下面這條指令aspnet_regiis -pdf "connectionStrings" "D:\WebApp"

6. 導出密鑰容器,密鑰資訊将被存儲在導出的xml檔案中,pri表示将公鑰和私鑰一起導出。

aspnet_regiis  -px "MyKeys" "D:/MyKeys.xml"  -pri

7.  有了這個xml檔案,就相當于有了密鑰容器,導出密鑰容器後可以對密鑰容器進行删除,删除指令如下。

aspnet_regiis  -pz  "MyKeys" 

8. 删除密鑰容器後,如果前面你沒有對Config檔案進行解密,那麼運作ASP.NET程式将會直接報錯。

    在本人實際操作中發現,如果對正在運作的ASP.NET應用程式的Web.Config檔案進行加密,加密後立即删除密鑰,此時點選運作(不調試)仍可正常通路。這表明Rsa解密操作在記憶體中執行,隻有重新生成解決方案或調試(會執行生成操作)後,通路才會報錯。

9. 現在可以将加密後的config檔案和導出的MyKeys.xml一起複制到伺服器上,此時運作網站将會直接報錯,需執行下面的導入指令。

aspnet_regiis -pi "MyKeys"  "D:/MyKeys.xml"

導入後,在本機通路ASP.NET網站會發現仍然報錯,提示無法open  Provider。這個坑最終在網上找到解決方法,如下面指令所示,需要為應用程式池設定對密鑰容器的通路權限。

aspnet_regiis -pa "MyKeys"   "IIS APPPOOL\MyWeb" -full

自此整個流程已結束,可以将上面這些指令封裝成2個批處理程式,一個是密鑰制作bat,一個是導入bat,如下所示。

在寫完這2個bat後,我想起前面的解密指令aspnet_regiis -pdf "connectionStrings" "D:\WebApp",它隻需要提供節點名稱和路徑。也就是說,如果攻擊者能夠在被攻擊的伺服器上執行cmd指令,那麼他就可以對config進行解密。這個問題如有前輩有更好的解決方式,歡迎您指導留言。

如果當初微軟編寫這個指令解析方法時,加上一個key的參數。那麼即使攻擊者能夠執行cmd指令,由于不知道key的名稱,是以仍然無法對config進行解密。

本文轉自 bxst 51CTO部落格,原文連結:http://blog.51cto.com/13013670/1943934