【潛盾機】web.config連線字串加密工具
ASP.NET 2.0起,web.cofig裡多了connectionStrings區段專門用以儲存資料庫連線字串,同時為避免連線字串中的帳號、密碼等機密資訊曝光,區段內容可以加密方式儲存。例如:
<connectionStrings>
<add name="PlaygroundConnectionString" connectionString="Data Source=(local);Initial Catalog=Playground;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
經加密後會變成:
<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>a44a3giX...略...o+VMsXS8os=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>TX5qKv+s...略...3YgrV5wcA==</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
如此,即便web.config遭竊,拿不到藏在伺服器主機的RSA金鑰,要破解取出帳號密碼資料難如登天。關於加解密web.config區段的做法,微軟MSDN有詳細說明:
但美中不足的是,這些加解密動作目前只能透過aspnet_regiis.exe命令列工具完成,要操作得弄清楚一堆參數。假設今天我們要加密web.config,並部署到三台機器上,全部操作如下:
- 用aspnet_regiis -pc "SharedKeys"–exp建立三台機器共用的RSA金鑰容器(Key Container)
- 以aspnet_regiis -px "SharedKeys" keys.xml -pri將RSA金鑰容器匯出成XML檔
- 將keys.xml複製到三台機器上
- 在三台機器上執行aspnet_regiis -pi "SharedKeys" keys.xml滙入RSA金鑰容器
- 在三台機器上執行aspnet_regiis -pa "SharedKeys" "NT AUTHORITY\NETWORK SERVICE"授與ASP.NET程式執行權限 (2010-08-30更新: IIS 7.5預設會使用IIS APPPOOL\YourAppPoolName帳號而非NT AUTHORITY\NETWORK SERVICE,詳情可參見保哥的文章,以下應用到授權的地方均比照,不再重複說明。)
- 在web.config中加入
<configProtectedData>
<providers>
<add keyContainerName="SharedKey" useMachineContainer="true"
name="SharedKey" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</configProtectedData>
- 使用aspnet_regiis -pe "connectionStrings" -app "/WebApplication" -prov "SharedKeys"加密連線字串區
- 將加密後的web.config部署到三台機器上
以上的步驟挺繁雜的,細節頗多,我一直覺得應該要有輔助工具簡化操作較為人性化,因此我寫了Web Config ConnectionString Ecnryptor!
它是一個小工具程式,說穿了只是提供GUI的方式讓使用者輸入選項,完成原本須透過aspnet_regiis.exe才能達成的web.config加解密及RSA金鑰容器管理功能。
操作介面還蠻直覺的,下拉選單可列出本機上所有的網站應用程式,選擇要處理的web.config,下方視窗就會顯示其內容,按下【編輯】鈕可開啟Notepad進行編輯。若web.config的connectionStrings尚未加密,可按下【加密】鈕對連線字串加密;至於已加密的web.config,【加密】鈕會變成【解密】鈕,也是按一下鈕就可解密,省卻原本複雜的操作。


針對RSA金鑰容器的建立、刪除、匯出、匯入,也一併提供了GUI介面進行管理。

另外,順便練習了一下.NET多語系程式開發,程式目前支援英語與正體中文。

以下說明幾種典型應用情境之操作步驟:
- 單一網站主機加密(使用預設加密金鑰)
a) 由下拉選單選取網站應用程式
b) 按下【加密】鈕
- 單一網站主機加密(指定特定金鑰容器)
a) 由下拉選單選取網站應用程式
b) 輸入金鑰容器名稱
c) 按下【加密】鈕
(web.config中會新增<configProtectedData><providers>並加入以金鑰容器名稱為名的RsaProtectedConfigurationProvider;若該金鑰容器不存在,系統會自動新增,但自動建立的金鑰容器無法匯出給其他機器共用。如針對Web Farm,請參考下一情境。)
d) 開啟【管理金鑰容器】功能
e) 輸入金鑰容器名稱,並按下【授權】鈕
- 多台網站主機共用指定RSA金鑰容器加密
a) 啟動【管理金鑰容器】功能
b) 輸入金鑰容器名稱,按下【建立】鈕
c) 按【授權】鈕
c) 按下【匯出】鈕,另存XML檔案
d) 將XML檔案複製到要部署的網站主機,在該主機執行Web Config ConnectionString Encryptor,使用【管理金鑰容器】功能,輸入金鑰容器名稱,選取XML檔案後按下【匯入】,並執行【授權】(操作完畢請將XML檔案刪除,防止金鑰外洩)
e) 在下拉選單選取網站應用程式
f) 輸入金鑰容器名稱
g) 按下【加密】鈕
h) 將web.config複製到要部署的網站主機
我將程式及原始碼放到CodePlex中,歡迎大家參考指教!
(聲明: 雖然我認為本工具原理簡單,出錯機率不高,但各位仍請自行衡量風險決定是否使用,在此恕不對它可能造成的任何損失負責。)
CodePlex: Web Config ConnectionString Encryptor