[.NET] 有關強式名稱 (Strong Name) 的兩三事

Strong Name 是 .NET Framework 中很特殊的一個特性,大多數的 .NET 開發人員不會使用到這樣東西,不過如果是從事 Framework 或是可轉散布型的軟體的開發人員,就需要知道這東西,因為它是一種組件識別 (asembly Identify) 機制,透過 Storng Name,它可以讓使用該組件的開發人員能確定這個組件是來自於建置的廠商或開發人員,而不是從中被竄改過。

Strong Name 是 .NET Framework 中很特殊的一個特性,大多數的 .NET 開發人員不會使用到這樣東西,不過如果是從事 Framework 或是可轉散布型的軟體的開發人員,就需要知道這東西,因為它是一種組件識別 (assembly identification) 機制,透過 Storng Name,它可以讓使用該組件的開發人員能確定這個組件是來自於建置的廠商或開發人員,而不是從中被竄改過。

Strong Name 分為幾個部份,你一定很常看到以下的宣告文字:

System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

這個宣告文字是組件型別字串 (Assembly Qualified Name),用來識別組件的相關資訊,常寫 ASP.NET 應用程式的人一定很常在 Web.config 中看到它。它會作為 Activator.CreateInstance() 需要的型別字串,這個字串中明確指示了型別,所在組件,版本,文化類型與金鑰等。而金鑰 (PublicKeyToken) 是判斷簡單型別與強式型別的基準,簡單型別的 PublicKeyToken 會是 NULL 值,而強式名稱的 PublicKeyToken 會是一組 8 位元的字串雜湊值。

強式名稱的組件不但可以強化組件的識別強度,它也是組件要安裝至 GAC (Global Assembly Cache) 的必要條件,GAC 的位置在 %WINDIR%\Microsoft.NET\assembly\ (不同的 Windows 版本路徑會不同),在裡面會看到許多 .NET Framework 本身的組件,而如果應用程式開發商需要安裝組件到 GAC 時,可以使用 .NET Framework 工具 gacutil.exe 來安裝組件。

強式組件有下列的功能:

  1. 具有強力的組件識別能力,可保證組件是來自開發商,而不是第三人。
  2. .NET Framework 的載入器會檢查組件的完整性,包含組件內的憑證的有效性,但組件必須要是由公開 CA 核發的憑證。
  3. 強式組件的版本識別能力會受到簽章的保護。

 

想要產生 PublicKeyToken,必須要有一張有效憑證,這個憑證可以是自我簽署憑證 (self-signed certificate),Visual Studio 給予了足夠的支援,只要按下一個鍵並輸入名稱就可以得到新的憑證,或是你可以使用 makecert.exe 來進一步自訂你的自我簽署憑證。有了憑證以後,只要將憑證加到專案中 (於專案屬性設定),在編譯時就會自動簽署,而你也可以使用 signtool.exe 進行簽署工作。

最後要提的是,強式名稱雖然具有很強的組件識別能力,但它卻沒有可保護程式不會被反組譯的能力-這是 IL 型程式語言的原罪 (Java 也一樣),只要使用可反組譯 MSIL 的工具,一樣可以反組譯具強式名稱的組件,就算它被安裝到 GAC 也一樣 (微軟也有提供可瀏覽 GAC 的擴充工具),如果想要進一步保護程式不會被反組譯,以 IL 型程式語言來說基本上是不太可能的,但可以使用混淆器 (Obsfucator) 攪亂程式碼變數與判斷式等,提升組件被反組譯時的判讀難度,或是把重要演算法使用 C/C++ 來開發,這樣就算是被反組譯,解讀難度也是比 IL 型的組件要高數十倍。

 

Reference:

http://msdn.microsoft.com/zh-tw/library/wd40t7ad.aspx
http://msdn.microsoft.com/zh-tw/library/xc31ft41.aspx
http://msdn.microsoft.com/zh-tw/library/yf1d93sz.aspx