創建一個強命名程序集首先需要獲得一個用強命名實用工具
(Strong Name Utility,即SN.exe,.NET SDK自帶)產生的密鑰。
下面簡要介紹一下SN.exe的一些用法。 要產生一個公鑰/私鑰對:
a)SN –k MyCompany.Keys
該命名告訴SN.exe創建一個名為MyCompany.keys的文件。MyCompany.keys文件將包含以對以二進制格式存儲的公有密鑰和私有密鑰。
b)查看公有密鑰:
首先生成一個只包含公有密鑰的文件: SN –p
MyCompany.keys MyCompany.PublicKey
然後用-tp參數查看:SN –tp MyCompany.PublicKeys
Public key is
00240000048000009400000006020000002400005253413
10004000001000100bb7214723ffc13901343df4b9c464ebf
7ef4312b0ae4d31db04a99673e8163768cc0a2a7062e731d
beb83b869f0509bf8009e90db5c8728e840e782d2cf928dae
35c2578ec55f0d11665a30b37f8636c08789976d8ee9fe9a5
c4a0435f0821738e51d6bdd6e6711a5acb620018658cce93
df37d7e85f9a0104a5845053995ce8
Public key token is 2dc940d5439468c2
創建好了公鑰/私鑰對,創建強命名程序集就很容易了。只需要把System.Reflection.AssemblyKeyFileAttribute特性加入到源代碼中就可以了:?[assembly:AssemblyKeyFile("MyCompany.keys")]
說明:公鑰/私鑰對文件的擴展名可以是任意的(也可以沒有),因為編譯的時候都是以元數據的格式讀取的。
4.程序集的部署方式
一個程序集有兩種部署方式:
a)私有方式
和應用程序部署在同一目錄下的程序集稱作私有部署程序集。弱命名程序集只能進行私有部署。
b)全局方式
全局部署方式將程序集部署在一些CLR已確知的地方,當CLR搜索程序集時,它會知道到這些地方去找。強命名程序集既可以進行私有部署,也可以進行全局部署。
5.如何部署強命名程序集(Strong Name Assembly)和GAC
a)GAC的概念
如果一個Assembly要被多個應用程序訪問,那麼他就必須放在一個CLR已確知的目錄下,並且CLR在探測到有對該Assembly的引用時,它必須能自動到該目錄下尋找這個程序集。這個已確知的目錄稱作GAC(Global Assembly Cache),就是全局程序集緩存。它一般位於下面的目錄下:<System Drive>:/Windows/Assembly/GAC。
GAC的作用就是提供給CLR一個已知的確定的目錄去尋找引用的 程序集。
b)GAC的內部結構
GAC是一個特殊的結構化的目錄,用Windows Explorer浏覽你會以為它只是一個包含很多程序集的普通目錄。其實不是這樣的,在命令行下查看,你會發現它實際上包含很多子目錄,子目錄的名字和程序集的名稱是相同的,但它們都不是實際的程序集,實際的程序集位於程序集名對應的目錄下。比如進入GCFWK子目錄,我們會發現其中又有很多的子目錄。機器內每一個安裝到GAC的GCFWK.dll在GCFWK中都會有一個子目錄。
這裡只 有一個目錄表明只有一個版本的GCFWK程序集被安裝。實際的程序集保存在每一個對應的版本目錄下。目錄的名稱以下劃線的形式分割為“(Version)_(Culture)_(PublicKeyToken)”。
GCFWK的語言文化信息為netture,就表示為0.0.0__bf5779af662fc055”。 表示得意義是: “GCFWK, Version=1.0.0.0, Culture=neutral,PublicKeyToken=bf5779af662fc055” 如果語言文化信息為”ja”,就表示”1.0.0.0_ja_bf5779af662fc055”
表示得意義是: “GCFWK, Version=1.0.0.0, Culture=ja, PublicKeyToken=bf5779af662fc055”
c)部署強命名程序集到GAC
GAC包含很多子目錄,這些子目錄是用一種算法來產生的,我們最好不要手動將程序集拷貝到GAC中,相反,我們應使用工具來完成這樣的工作。因為這些工具知道GAC的內部結構J
在開發和測試中,最常用的工具就是GACUtil.exe。 在GAC中注冊程序集跟COM注冊差不多,但相對更容易:
1.把程序集添加到GAC中: GACUtil /i sample.dll (參數/i是安裝的意思)
2.把程序集移出GAC GACUtil /u sample.dll (參數/u就移除的意思)
注意:不能將一個弱命名程序集安裝到GAC中。
如果你試圖把弱命名程序集加入到GAC中,會收到錯誤信息:”
Failure adding assembly to the cache: Attempt to install an assembly without a strong name”
d)強命名程序集的私有部署
把程序集安裝到GAC有幾個好處。首先,GAC使得很多程序可以共享程序集,這從整體上減少了使用的物理內存;其次,我們很容易將一個新版的程序集部署到 GAC中,並通過一種發布者策略(差不多就是一種重定向方法,比如將原來引用版本為1.0.0.0程序集的程序,通過更改它的配置文件,轉而讓程序去引用版本為2.0.0.0的程序集)來使用新版本;最後,GAC還提供了對不同版本程序集的並存(side-by-side)管理方式。但是,GAC的安全策略通常只允許管理員更改,同時,向GAC中安裝程序集也破壞了.NET框架的簡單拷貝部署的許諾。
除了向GAC或者以私有部署方式部署強命名程序集之外,我們還可以將強命名程序集部署在僅為一小部分程序知道的某個任意目錄下。配置每一個應用程序的 XML配置文件,讓它們指向一個公有目錄,這樣,在運行時,CLR將知道到哪裡去找這個強命名程序集。但這樣又有可能會引發”DLL Hell”的問題,因為沒有哪個程序可以控制這個程序集何時被卸載。這在.NET中也是不被鼓勵的。
強命名策略:
生成公鑰與私鑰對,並對私鑰做嚴格的保護
生成:sn -k keyfile.snk 公鑰與私鑰對
抽取公鑰:sn -p keyfile.snk public.snk 從keyfile中抽取公鑰保存到public.snk文件中,以對程序集進行遲簽名
跳過驗證:sn -Vr assembly 對assembly在開發用機上進行跳過驗證處理,該assembly不是已簽名的
簽名:sn -r assembly keyfile.snk 對assembly 進行遲簽名,這一步是在發布之前做