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

在將ASP.NET項目部署到服務器上時,內網環境下Web.Config每每是直接複製過去。對於外網環境,則須要對Web.Config文件進行加密。web

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

前者在本機加密Web.Config後,只能在本機進行解密,若是須要將Config文件複製到外部主機,則沒法進行解密。後者在本機加密Config文件後,能夠處處密鑰容器,當把Config文件複製到外部主機後,可對先前導出的文件進行導入功能,導入後既可自動解密。c#

因爲常常須要複製Config文件到外部主機,所以Rsa保護程序更加適用於實際業務場景,本文將詳細介紹RsaProtectedConfigurationProvider程序的使用步驟。api

1. 使用RsaProvider提供程序,須要首先進入.NET Framework運行環境,能夠配置環境變量或使用cd指令。服務器

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

2. 接着即可以使用aspnet_regiis.exe建立一個Rsa密鑰容器。密鑰容器分用戶級別和計算機級別兩種狀況,因爲使用用戶級別密鑰沒什麼益處,通常使用計算機級別既可。asp.net

aspnet_regiis -pc "MyKeys" -expide

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配置節點下面,這樣會報錯,建議放在你須要加密節點的後面。

   <configProtectedData>
      <providers>
         <add name="MyProvider"
              type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,
                    Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,
                    processorArchitecture=MSIL"
              keyContainerName="MyKeys" 
              useMachineContainer="true" />
      </providers>
   </configProtectedData>

 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應用程序。

  <connectionStrings configProtectionProvider="MyProvider">
    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
      xmlns="http://www.w3.org/2001/04/xmlenc#">
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
          <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
          <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <KeyName>Rsa Key</KeyName>
          </KeyInfo>
          <CipherData>
            <CipherValue>X3XoBfbo/h9QUeVUV8A1EGMM0NQuBnhfuC/iV1e7CCmGaiRt9ogmICenTK8VAmGfhufPzWFu5UUHSiO/6BIvYPEO5WoWlj3h5/sUQmRj6NsAJOnrnYHEjta4oQb4XajxazWcf3HUeWR0mG4wDCiUfTZaRIRmXkGgfbxewpsKJ5k=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>suqFgGjGFaon62YNI2VM5SQymcf4yyAku9fWQuvgClj1bfqixK9kIs9IE0I0m2u4gLbF+y0xPharfcOFJpXHDwHoaCrNQsxsutqiXquX67bYcJeYaMz5ja9ebqAtQvKIiZ/kHGvFIPXSCg5HiW/GGQwaf3FESVEsOaSAJZ3JJk9MlkkwDd6LepgtcCVjLnEK0lOeEFznrngizFFZWAsYjh5UCF5lNxNxf/IBwtznsfiFi2tV1F4sx9HkJEEryf5MEtu1RAA/wqarMvn7dlXhpGconpNPXA1IGlTmaZ/S1bR/FsO39skgHrs+OHsDMbJrI5ZO4TXXbK/DD86GPzu9JXrVKNVImzzW0V8aMc2HcVNClPsMwwgGaH6PNhE0xkjV6YH77XcLdVsKibvnwMlO/4kjGKoNXaSkFBoAEgprzi8=</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>

 若是須要解密,能夠執行下面這條指令aspnet_regiis -pdf "connectionStrings" "D:\WebApp"

<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-WebApp-20170622060005.mdf;Initial Catalog=aspnet-WebApp-20170622060005;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

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,以下所示。

@echo on
cd C:\Windows\Microsoft.NET\Framework\v2.0.50727

::設置config地址,config文件要在E:\test下面
set configAddress="E:\test"

::建立RSA密鑰容器
aspnet_regiis -pc  "MyKeys" -exp

::設置密鑰容器訪問權限
aspnet_regiis -pa "MyKeys" "NT AUTHORITY\NETWORK SERVICE"

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

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

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

::刪除密鑰容器
aspnet_regiis  -pz  "MyKeys" 

pause
@echo on
cd C:\Windows\Microsoft.NET\Framework\v2.0.50727

::刪除舊的密鑰容器
aspnet_regiis  -pz  "MyKeys" 

::導入新的密鑰容器
aspnet_regiis -pi "MyKeys"  "D:/MyKeys.xml"

::設置應用程序池的訪問權限
aspnet_regiis -pa "MyKeys"   "IIS APPPOOL\MyWeb" -full

pause

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

若是當初微軟編寫這個指令解析方法時,加上一個key的參數。那麼即便攻擊者可以執行cmd指令,因爲不知道key的名稱,因此仍然沒法對config進行解密。

聲明:本文原創發表於博客園,做者爲方小白 ,若有錯誤歡迎指出。本文未經做者許可不準轉載,不然視爲侵權。

相關文章
相關標籤/搜索