生成、部署和管理
1 如何生成強簽名的程序集
2 如何把程序集放入GAC中
3 延遲簽名及其作用
4 程序集的版本分哪幾部分
?
1 如何生成強簽名的程序集
在生成程序集時,CLR提供了兩種可選類型:
強簽名程序集。
弱簽名程序集。
強簽名程序集是一個帶有公鑰和數字簽名的程序集,每個強簽名都可以由四個元素來唯一標識,它們分別是:文件名、版本號、語言文化和公鑰。這些信息都被包含在程序集的清單之中。相對于強簽名程序集,弱簽名程序集擁有完全一樣的元數據、CLR文件頭和程序集清單,唯一不同的是弱簽名程序集沒有公鑰,也不進行數字簽名。弱簽名程序集不能被放入全局程序集緩存(GAC)中,只能進行私有部署。
這里簡單介紹一下加密的基本概念。當我們在處理私密信息的時候,就需要用到加密技術。常用的加密技術有對稱加密技術、非對稱加密技術和不可逆加密技術。.NET的公鑰私鑰機制屬于非對稱加密技術。非對稱加密的基本概念是加密方用公鑰對信息加密,而解密方需要使用公鑰和與其配對的私鑰對已加密信息進行解密。非對稱加密的特點在于公鑰可以公開,加密算法公開,而唯一控制解密的關鍵就在于私鑰,所以在非對稱加密中,公鑰往往隨加密信息一起發送到接收方,而接收方通過公鑰來尋找與其配對的私鑰并且進行解密。現在常用的非對稱算法有RSA算法和DSA算法。
回到.NET的加密機制中,當生成一個強簽名程序時,其公鑰將被添加到程序清單之中。同時,在程序集被發布(Publish)時,也會生成一個數字簽名,數字簽名包含了程序集清單的散列值,而程序集清單又包含了該程序集中所有模塊的散列值,在這種情況下,除非擁有程序集的公鑰和私鑰,否則將無法對程序集做任何改動。可見在強簽名程序集中,公鑰和數字簽名一起實現了對程序集的保護。
下圖展示了一個強簽名程序集的內部結構,以及引用這個程序集的其他程序集的結構。程序集2引用了程序集1中的引用,所以在程序集2的CLR頭中,保留了程序集1的公鑰標記。
? 注意:由于公鑰過長,程序集引用可以使用公鑰標記來代替公鑰。公鑰標記是指公鑰的一個散列值,長為8個字節。
了解了公鑰的基本原理之后,現在筆者以C#的編譯器CSC.exe為例,來說明如何生成一個強命名的程序集。首先,需要為新的強命名程序集準備一對唯一的公鑰/私鑰。.NET Framework提供了一個很實用的工具:sn.exe。
打開一個Visual Studio 2010的命令臺,輸入下面這條命令:
sn –k C:/MyPublicPrivateKey.snk
sn.exe就會為我們在C盤根目錄下生成一個MuPublicPrivateKey.snk文件。這個文件把公鑰和私鑰拼接在了一起,大小為596字節,其中前160字節屬于公鑰,而后436字節屬于私鑰。用戶可以控制sn.exe的輸入參數來僅僅得到公鑰或者實現其他功能。
準備好了公鑰/私鑰對,就可以生成一個強命名程序集了。打開一個Visual Studio 2010自帶的命令臺并且進入xxx.cs所在的目錄,輸入以下命令:
csc.exe /t:library xxx.cs /keyfile:C:\MyPublicPrivateKey.snk
一個名為xxx的強命名程序集就被生成了,讀者可以嘗試自己編寫一個引用該強命名程序集的程序集,并且嘗試用一個弱命名程序集來代替它。當然,這是沒辦法實現的,公鑰標記和數字簽名將很好地保證程序集不能被隨意篡改。
生成強簽名的程序集需要有公鑰/私鑰對。在得到了公鑰/私鑰對后,就可以控制編譯器的輸入參數來得到一個強簽名的程序集。對于C#的編譯器CSC.exe來說,可以用/keyfile參數來制定使用那個公鑰/私鑰文件。
所謂的GAC,就是全局程序集緩存(Global Assembly Cache)。被放入GAC的程序集,無論在何處被其他程序集引用,都可以保證自己能夠被CLR找到并且加載。簡單來說,GAC是一個有規范的目錄結構。如果主機使用的是Windows操作系統,并且操作系統被安裝在c:\windows下,那么GAC會被安裝在c:\windows\assembly\下。
這種顯示方式和一般的文件夾顯示方式有很大區別。實際上,.NET Framework附帶了一個全局程序集緩存的查看器assembly viewer,上圖就是這個查看器的顯示功能,它很清楚地列出了唯一標識一個程序集的4個元素:名稱、版本、文化和公鑰標記,同時,它也列出了另外一個影響程序集在GAC中目錄結構的元素:處理器體系結構。讀者可以通過關閉查看器功能來親眼看一看GAC目錄的真正面目。具體做法是在注冊表HKEY_LOCAL_ MACHINE\Software\Microsoft\Fusion下建立一個名為DisableCacheViewer的DWORD值,并且將該值設為0。讀者將會發現GAC是一個多層的目錄結構,其結構符合一定的規范。
注意 除非需要學習GAC目錄結構,否則在任何時候都不應該手動地去修改GAC目錄,任何對GAC目錄的操作都應該通過工具實現。
在一般情況下,GAC具有如下優點:
- 程序集被多處引用時,可有效減少內存成本。
- 通過發布者策略可以有效地發布程序集的最新版本。
- 同一程序集的多個版本可以共存,并且可以通過配置進行切換。
是否所有的程序集都可以被放入GAC中呢,答案是否定的。只有帶有公鑰的強簽名程序集才能被部署到GAC中去,在程序集被放入GAC時,.NET將檢查程序集的CLR頭和加密值,保證程序集未被篡改。把程序集放入GAC中可以手動地部署,也可以通過工具進行部署。最簡單的方法就是通過前面介紹的assembly viewer直接把程序集拖入到assembly viewer顯示的GAC目錄下。
? 注意:這里提到的拖放,實際上還是使用了assembly viewer的功能,而不同于直接把程序集復制到GAC文件夾下。再次強調,讀者不應該手動地去修改破壞GAC目錄結構。
.NET Framework還提供了一個工具來有效地管理GAC:GACUTIL.exe。筆者生成了一個強簽名的程序集:Compile.dll。現在,嘗試將其放入GAC中:
Gacutil –i Compile.dll
進入assembly viewer,讀者將會發現剛剛加入的這個新程序集:Compile.dll,0.0.0.0。
GAC是一個具有特定目錄結構的文件夾,所有強簽名的程序集都可以被放入GAC中。可以通過.NET Framework自帶的assembly viewer來簡單地拖動添加一個程序集到GAC中,也可以利用諸如gacutil.exe等工具使用命令行來添加。總之,任何方法歸根結底,都是根據GAC的規范和程序集本身的特性,在GAC目錄下建立相應的子目錄結構。
當生成一個強簽名程序集時,在CLR頭部中會加入公鑰和數字簽名,公鑰和數字簽名能夠保護程序集不被隨意篡改。但是,有經驗的.NET程序員或者項目經理會有這樣的切身經歷,帶有防篡改功能的程序集在開發和測試階段會變得極其不方便。為了使用和修改該程序集,項目組不得不把非常重要的私鑰分發出去,而這將會給項目的保密性帶來極大的威脅。
所以,在項目的開發和測試階段,延遲簽名技術會被經常使用。顧名思義,延遲簽名的基本概念就是把私鑰加密延遲到項目真正發布時再進行。而在開發和測試階段,程序員將只用一個公鑰來生成強簽名程序集。這樣程序集的CLR頭中只有公鑰而沒有數字簽名,數字簽名的空間將會被保留,而且所有的文件也不經過加密處理。
在CLR頭中,數字簽名的空間被保留了下來,并且沒有對文件進行HASH處理。而在其他方面,延遲簽名不會產生任何影響。說到這里,讀者可能會有這樣的疑問,延遲簽名的程序集能否被放入到GAC中呢?回顧一下在上一節中介紹的,GAC對程序集的要求為該程序集是帶有公鑰的強簽名程序集。延遲簽名的程序集帶有一個公鑰,所以原則上是可以被放入GAC的,但由于GAC會對程序集進行加密驗證,延遲簽名的程序集缺乏私鑰而沒有經歷任何HASH處理,所以延遲簽名的程序集在被放入GAC之前,需要通知.NET不要對該程序集進行加密驗證。
延遲簽名就是指把對強簽名程序集的私鑰加密和數字簽名延遲到實際發布時進行。延遲簽名提高了開發測試階段的效率,也方便了機構和項目組管理自己的私鑰。
有四個元素可以唯一標識一個強簽名程序集,分別是名字、版本號、文化和公鑰。程序集的版本號通常由四個部分組成,它們是:
- 主版本號(Major Version)
- 次版本號(Minor Version)
- 內部版本號(Build Version)
- 修訂號(Revision Version)
默認地,版本號越大代表系統越新。一般主版本號和次版本號的定義比較明確,當系統經歷一個比較大的升級,主版本號會有改動,而在一個主版本中,小功能的發布則會通過次版本號進行發布。關于內部版本號和修訂號,理解的分歧會更大一點。在一般情況下,一個內部版本號代表系統內部的一次集成周期,而一個修訂號,則代表集成周期中的一次編譯。
例如某個目前版本號為12.2的系統組織內部,決定在新版本12.3發布前進行6個集成周期,每個集成周期歷時一周,而編譯系統則被設置成每天午夜編譯一次。這樣在通常情況下,這個系統將針對6個集成周期形成6個內部版本號,從12.3.1到12.3.6。而對于每個內部版本將會經歷7次編譯,則系統會擁有7個修訂號。例如第二版本,將會擁有這樣7個版本號:12.3.2.1到12.3.2.7。
注意:版本號的劃分并沒有明確的規范。但組件發布者應該按照常用定義來確定產品的版本號,怪異的版本號劃分將會誤導組件使用者。
?
轉載請注明出處:
作者:JesseLZJ
出處:http://jesselzj.cnblogs.com