緣起:
今天無聊在隨意亂看我們公司建立站台的程式碼時,發現一個有趣的東西,那部份的程式碼有用
#region Config加密 包起來,然後還有用 C# 的 Process 類別來執行一個叫
aspnet_regiis.exe 的程式碼,所以就好奇去查,發現,原來我們的 webconfig
就是用這個東西來加密的。
想自己動手操作一次並記錄。參考文章
建立金鑰容器:
我一開始是去確定我電腦上有沒有 C:\Windows\Microsoft.NET\Framework\v4.0.30319
這資料夾,發現有,所以再來就照著下指令
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pc "birdshiutest" -exp
-pc "金鑰名稱",-exp 代表設定金鑰允許匯出
這就讓我好奇,能不能用 aspnet_regiis.exe 來條列有哪些 container,我稍微找了一會後,發現好像不行,但在這篇文章看到,可以到 %ProgramData%\Microsoft\Crypto\RSA\MachineKeys 這邊去找。我到那個資料夾後,看到一些以 guid 命名的檔案,它們不是文字檔,所以不能直接用文字編輯器讀
對 web.config 加密:
再來要試著對 webconfig 加密,我選了之前建的 ASP WebForm
專案來當白老鼠 (就那個WebSite1),為了避免弄爆 webconfig 後救不回專案,所以我先對它做備份。
開始加密,首先,要編輯 web.config,在 <configuration>
節點加入
<configProtectedData defaultProvider="TheKeyProtectedProvider">
<providers>
<add name="TheKeyProtectedProvider"
type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
keyContainerName="birdshiutest"
useMachineContainer="true" />
</providers>
</configProtectedData>
再來,要加密 connectionStrings
的區段。我在觀察完文章中指令的格式後,判斷是
aspnet_regiis.exe -pef "{webconfig要加密的區段}" "{webconfig所在資料夾路徑}" -prov "{webconfig裡的protectedprovider名字}"
我自己下的指令,格式是長這樣
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pef "connectionStrings" "." -prov "TheKeyProtectedProvider"
然後這是下完指令的回應
這時再去看 webconfig,哇 ~~ connectionStrings
區段真的有被加密了
從公司的程式碼中,我發現,你是可以對同支 webconfig 多次呼叫 aspnet_regiis.exe 來加密它上面的各個區段,還發現,對於 {webconfig要加密的區段} 這參數,它是以 <configuration> 為 root,然後像 unix 系統的路徑一樣來指定 <configuration> 內的 node。
比如說,如果你想加密 configuration > system.web >
sessionState,指令可以下
解密:
解密的話,指令格式是這樣 (pdf XD)。我這時才發覺,pef 的 e
是 encrypt,而 pdf 的 d 是 decrypt
aspnet_regiis.exe -pdf "{要解密的webconfig區段}" "{webconfig所在資料夾路徑}"
我指令實際是這樣
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pdf "connectionStrings" "."
下完指令後
小插曲:
目前,我那個 WebSite1 測試專案下的
webconfig,有加密的區段就 connectionStrings
這時直接在 IIS 瀏覽專案站台
我原本以為,這是因為我沒有做權限的設定,帳戶無法存取金鑰,無法對
webconfig 做解密造成的問題。所以就再用 aspnet_regiis.exe 下了一堆針對 birdshiutest
金鑰存取權限的指令,結果到最後才發現,把那個 entityFramework
區段砍掉就正常了 ....。
所以,其實我加密完專案的 webconfig 後,IIS
當下其實就能正常解密 webconfig
檔,不需再去做有的沒的權限設定。也有可能,是因為我的網頁不需要讀取
connectionStrings 的值就能正常運作,因為我還有測試把加密過的
connectionStrings 區段給移除,網站還是能正常執行。
為了確認 IIS 是否真的能正常解密 webconfig 檔,我在
webconfig 檔的 <configuration> 裡加入
<appSettings>
<add key="test" value="test" />
</appSettings>
然後下指令來加密,appSettings
區段,我再來去專案下新增一個測試用的 asp 頁面,它的功能就只是讀取 appSetting
裡的 test 值,然後顯示在 Literal。
aspx頁面
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="birdshiutest.aspx.cs" Inherits="birdshiutest" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Literal runat="server" ID="litTest"></asp:Literal>
</div>
</form>
</body>
</html>
cs頁面
using System;
using System.Configuration;
public partial class birdshiutest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
litTest.Text = ConfigurationManager.AppSettings["test"].ToString();
}
}
接著再瀏覽站台,有看到頁面顯示 test,所以代表 iis
確實能正常解密 "加密後的 webconfig 檔"。
我在查文章時還有看到這篇,有學到可以用
System.Security.Principal.WindowsIdentity.GetCurrent().Name
來取得站台目前使用的帳戶,我看是顯示 "IIS APPPOOL\DefaultAppPool"。
匯出與匯入金鑰:
匯出金鑰的語法
aspnet_regiis.exe -px "{金鑰名稱}" {匯出路徑}.xml -pri
我指令一開始是下這樣,用管理員身份開 cmd
來執行
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -px "birdshiutest" C:\birdshiutest.xml -pri
它跳錯誤給我
所以我就去查一下那個 -pri
代表什麼。發現是匯出時包含 private key。我記得一開始的時候,加上
-pri
的參數,跑起來是正常的,可能是我後來不知亂動了什麼,導致不能正常匯出它的
private key,為了驗證,我後來還有再新增一個金鑰 container 叫
"birdshiutest2",匯出它,它的匯出功能確實是正常的。
完成後就能在 C:\ 下面看到 birdshiu2.xml 檔
再來就可以把金鑰的 xml
檔給丟到其它台電腦,然後匯入金鑰
aspnet_regiis.exe -pi "{金鑰名稱}" {金鑰所在路徑}.xml
匯入的功能我就沒自己試了,以後有機會再紀錄,聽說匯入金鑰時還會碰上權限設定的問題,這個也之後一併試。
刪除金鑰:
刪除的 cmd 格式
aspnet_regiis.exe -pz "{金鑰名稱}"
我在本機上下
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pz "birdshiutest"
沒有留言:
張貼留言