星期三, 12月 26, 2012

設定檔加密

在 .NET 應用程式或網站,可以利用設定檔(app.config / *.exe.config / Web.config)調整程式的行為,常見的開發環境與執行環境各自有不同的資料連線字串,放在設定檔就很適合。但是接著問題來了,資料連線字串通常含有密碼,如果以明文存放,無疑是對具有伺服器檔案存取權限的人們毫不設防。也許猛一看這沒什麼,畢竟對伺服器可以存取的權限控管本來就應該嚴謹,只是少數人知道而已。但對於一家「所有資料庫都用同一帳號密碼」的資訊服務公司而言,是很高的風險,因為他們在所有客戶端的資料庫,只要有一個洩漏,也就等於所有客戶的資料庫都同時被破。

其實微軟有個基本的加密機制可以運用,我這樣拿來搭配一個應用程式:
  1. 部署到客戶端時,設定檔內的連線字串還是明文。
  2. 在用戶端第一次執行,最開始的程式會檢查設定檔,如果是明文則加密。
  3. 其後每一次執行,最開始的程式仍然會檢查設定檔,如果已加密則不變。
  4. 後續的程式會用到設定檔內容,透過 ConfigurationManager 其實不用為解密煩惱。
  5. 萬一要更改設定,從另一個未加密的「範本設定檔」開始。
看起來不錯?我本來也是這麼想,但要真正了解才會知道這樣的保障是不是足夠。由於我只處理資料連線字串,從範例東抄西剪之後,用下面的程式:

ConnectionStringsSection css = // 取得連線字串段落
css.SectionInformation.ProtectSection("RSAProtectedConfigurationProvider");

引號內的部份是什麼意思?查了半天,總算在 machine.config 得到線索:

<configuration>
    <configProtectedData>
        <providers>
            <add name="RSAProtectedConfigurationProvider" keyContainerName="NetFrameworkConfigurationKey"...

這是一把可用來加解密的金鑰,它可透過以下的命令匯出:

aspnet_regiis -px NetFrameworkConfigurationKey C:\out.xml -pri

但這會有個小問題,「機碼用在特定狀態時無效」,這是什麼?先放著,試試以下這個:

aspnet_regiis -px NetFrameworkConfigurationKey C:\out.xml

就不會有問題。到此學到了一些事:
  1. 系統內可以有很多金鑰,在預設情況下,一把名為「NetFrameworkConfigurationKey」的金鑰可用來加密設定檔。
  2. 這把金鑰是「不可匯出私鑰」的,只是錯誤訊息太糟了。
接著我好奇,在某部電腦上加密的設定檔,可不可以直接複製到另一部電腦上用?當然是搭配著相關金鑰一起移。既然上面那個不可匯出私鑰,只好重新打一把:

aspnet_regiis -pz NetFrameworkConfigurationKey

aspnet_regiis -pc NetFrameworkConfigurationKey -exp

aspnet_regiis -px NetFrameworkConfigurationKey C:\out.xml -pri

將 out.xml 移到另一部機器上:

[Computer2] aspnet_regiis -pi NetFrameworkConfigurationKey C:\out.xml

果然是可用的。

星期二, 10月 16, 2012

新滑鼠啟用

Microsoft Arc Touch,左鍵硬了點也遠了點,以觸控取代滾輪還蠻新鮮的。

星期四, 9月 06, 2012

網頁一片空白?停用代理伺服器也許可解決

IE 無法安裝附加元件的解決方法

  1. 安全性->ActiveX「不」篩選。
  2. 網際網路選項->進階->安全性->「不」啟用記憶體保護以協助避免網路攻擊。
  3. 執行 iexplore -extoff 或在網址列輸入 about:NoAdd-ons,進入「關閉所有附加元件」的狀態,再到管理附加元件->顯示所有附加元件,一一停用。
  4. 關閉所有瀏覽器再開啟,應該就可以安裝附加元件。
  5. 如果是 Windows 7,還有一個「群組原則設定」必須考慮,可參考 http://www.sevenforums.com/system-security/145610-cannot-install-active-x-control.html 其中 jav 的回覆。
[2014/06/25 補充]
  1. 漏了前提假設 :附加元件是經「受信任憑證中心」所發憑證的簽署。如果不是這樣,多半調低安全性即可解決。
  2. 恢復瀏覽器所有的預設值也許有幫助。
  3. 如果是 Windows 7,又將「使用者帳戶設定」拉到最低,也會因為無法提示造成問題,只要恢復使用者帳戶設定回預設值即可。

星期三, 7月 25, 2012

.NET ActiveX 元件的版本控制

一般 ActiveX 標籤若有附加版本資訊,就有自動下載更新的機制。但依賴 .NET 的 ActiveX 元件,必須額外寫入以下機碼作為比較基礎:
[32 bits OS] HKEY_CLASSES_ROOT\CLSID\{...}\InstalledVersion
[64 bits OS] HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{...}\InstalledVersion
微軟經常沒把事情做完呀!
補充一下:透過 REG ADD 寫入上述機碼時,不必判斷作業系統是哪一種,一律當作是 32 bits 來寫就是了,64 bits 的寫入位置會自動調整。

星期五, 7月 20, 2012

可攜視窗作業系統

以往總想用 USB 接一個可 Windows 開機的硬碟,一直沒試成功。近來需要 Windows 64 位元的測試環境,但本機是 32 位元,VirtualBox 上的 Guest 一直有問題,只好試著先裝個可攜的 64 位元 Linux,再加上 VirtualBox 和 Windows 64 位元 Guest,有點麻煩,但可以用。
重點是 Linux Live CD 不要直接放在外接硬碟上,而是要另外放在別的 USB Disk(小容量,8G 就夠了),開機後先將 Linux 裝在大容量的外接硬碟上,再從大硬碟開 Linux,裝 VirtualBox。

星期五, 6月 08, 2012

以強式名稱簽署第三方組件

專案要用到第三方開放原始碼的組件,而且希望簽署產出,所以被引用的組件需要符合強式名稱,但是沒有,怎麼辦?若有完整的原始碼當然容易,但也許沒有(或不想大動別人的東西)的時候,還是有方法的。先準備以下內容:
  1. 安裝 Windows SDK
  2. 簽署用的 CodeKey.pfx
  3. 要開刀的 WeakName.dll
處理步驟如下:
  1. 反組譯組件,指令為 ildasm.exe /all /out=WeakName.il WeakName.dll,除了正常輸出之外,還附帶 WeakName.res。
  2. 把金鑰拆出,指令為 sn.exe -p CodeKey.pfx CodeKey.snk。
  3. 重組指令為 ilasm.exe /dll /resource=WeakName.res /key=CodeKey.snk WeakName.il,產出結果就是符合強式名稱的組件。
  4. 確認用的指令為 sn.exe -T WeakName.dll。
需要注意的是,「以強式名稱簽署組件」指的是在 Visual Studio 開發工具裏的 Project -> Properties -> Signing -> Sign the assembly,很容易與「數位簽署檔案」混淆。依據微軟官方說法:
  • 強式名稱工具 (sn.exe) 可以協助您以強式名稱簽署組件,提供了金鑰管理、簽章產生和簽章驗證的選項。
  • 簽署工具 (signtool.exe) 能夠數位簽署檔案、驗證檔案中的簽署或為檔案加上時間戳記。
也順便提一下,已經數位簽署的檔案,在檔案總管按滑鼠右鍵看內容,會多出一個「數位簽章」的頁籤。要達成此效果的指令如下:
  • signtool.exe sign /f CodeKey.pfx /p secret /t http://timestamp.verisign.com/scripts/timstamp.dll /v WeakName.dll

星期三, 5月 30, 2012

瀏覽器擴充能力

有點好奇,非 IE 瀏覽器到底能不能跑 ActiveX?試了 Firefox + IE Tab / Chrome + IE Tab 都過關,不過前提是「真的有裝 IE」,也就是說非微軟作業系統還是有困難。
管他的,還沒見過使用者像我以前那樣,為了省錢也為一口氣,硬是不裝 Windows OS。