強名稱簽名的方法:
強簽名:
1. 可以將強簽名的dll注冊到GAC,不同的應用程序可以共享同一dll。
2. 強簽名的庫,或者應用程序只能引用強簽名的dll,不能引用未強簽名的dll,但是未強簽名的dll可以引用強簽名的dll。
3. 強簽名無法保護源代碼,強簽名的dll是可以被反編譯的。
4. 強簽名的dll可以防止第三方惡意篡改。
強簽名的方法:
1. 有源代碼:
1.1 使用vs tool command:snk –k mykey.snk 生成簽名公鑰。
1.2 將公鑰加入項目中,並設置項目屬性,設置簽名公鑰
1.3 重新生成項目。
2. 沒有源代碼。
2.1 創建強簽名鍵:
sn.exe -k key.snk
2.2 反匯編dll為il
ILDASM.exe SomeLibrary.dll /OUTPUT=SomeLibrary.il
該指令會反匯編該dll並生成SomeLibrary.il,如果該dll含有嵌入的resource,
則會有SomeLibrary.res文件產生,並有相應的嵌入資源文件產生。
2.3 重新匯編為dll
ILASM.exe SomeLibrary.il /DLL /OUTPUT=SomeLibrary.dll /KEY=key.snk
如果有嵌入的資源文件,則需要加上 /RESOURCE=SomeLibrary.res
強簽名的dll與未簽名的在反編譯后的區別:
未簽名的:
強簽名的:
更多詳細信息參考 StringNaming
http://windowsdevcenter.com/pub/a/dotnet/2003/04/28/strongnaming.html
1.打開“Visual Studio 2008 命令提示”命令行工具。
2. 用Sn.exe 生成一個Public/Private Key Pair 文件:Sn -k test.snk. 如果不指定大小,它的大小就是596 bytes(128 publicKey,32 publicKey Header, 436 PrivateKey)。
3. 添加 [assembly: AssemblyKeyFile(@"test.snk")] 到程序的AssemblyInfo.cs中,也可以在Build Option中指定(/keyfile:test.snk ). 再重新生成test.dll. 在VisualStudio中還可以用工程屬性指定.
4. Sn -v test.dll 查一下test.dll是不是已經是一個strongname的程序了,輸出:test.dll is valid。表示成功生成了一個具有PublicKey的程序 Sn -T test.dll 可以得到這個assembly的PublickKeyToken。
為什么使用強名稱簽名:
通過簽發具有強名稱的程序集,您可以確保名稱的全局唯一性。強名稱還特別滿足以下要求:
強名稱依賴於唯一的密鑰對來確保名稱的唯一性。任何人都不會生成與您生成的相同的程序集名稱,因為用一個私鑰生成的程序集的名稱與用其他私鑰生成的程序集的名稱不相同。
強名稱保護程序集的版本沿襲。強名稱可以確保沒有人能夠生成您的程序集的后續版本。用戶可以確信,他們所加載的程序集的版本出自創建該版本(應用程序是用該版本生成的)的同一個發行者。
強名稱提供可靠的完整性檢查。通過 .NET 框架安全檢查后,即可確信程序集的內容在生成后未被更改過。但請注意,強名稱中或強名稱本身並不暗含某一級別的信任,例如由數字簽名和支持證書提供的信任。
在引用具有強名稱的程序集時,您應該能夠從中受益,例如版本控制和命名保護。如果此具有強名稱的程序集以后引用了具有簡單名稱的程序集(后者沒有這些好 處),則您將失去使用具有強名稱的程序集所帶來的好處,並依舊會產生 DLL 沖突。因此,具有強名稱的程序集只能引用其他具有強名稱的程序集。
GAC
一、GAC的作用
全稱是Global Assembly Cache作用是可以存放一些有很多程序都要用到的公共Assembly,例如System.Data、System.Windows.Forms等等。這樣,很多程序就可以從GAC里面取得Assembly,而不需要再把所有要用到的Assembly都拷貝到應用程序的執行目錄下面。舉例而言,如果沒有GAC,那么勢必每個WinForm程序的目錄下就都要從C:\WINDOWS\Microsoft.NET\Framework\vX下面拷貝一份System.Windows.Forms.dll,這樣顯然不如都從GAC里面取用方便,也有利於Assembly的升級和版本控制。
二、強命名程序集
因為不同的公司可能會開發出有相同名字的程序集來,如果這些程序集都被復制到同一 個相同的目錄下,最后一個安裝的程序集將會代替前面的程序集。這就是著名的Windows “DLL Hell”出現的原因。
很明顯,簡單的用文件名來區分程序集是不夠的,CLR需要支持某種機制來唯一的標識一個程序集。這就是所謂的強命名程序集。
一個強命名程序集包含四個唯一標志程序集的特性:文件名(沒有擴展名),版本號,語言文化信息(如果有的話),公有秘鑰。
這些信息存儲在程序集的清單(manifest)中。清單包含了程序集的元數據,並嵌入在程序集的某個文件中。
下面的字符串標識了四個不同的程序集文件:
“MyType, Version=1.0.1.0,
Culture=neutral, PublicKeyToken=bf5779af662fc055”
“MyType, Version=1.0.1.0,
Culture=en-us, PublicKeyToken=bf5779af662fc055”
“MyType, Version=1.0.2.0,
Culture=neturl, PublicKeyToken=bf5779af662fc055”
“MyType, Version=1.0.2.0,
Culture=neutral, PublicKeyToken=dbe4120289f9fd8a”
如果一個公司想唯一的標識它的程序集,那么它必須首先獲取一個公鑰/私鑰對,然后將共有秘鑰和程序集相關聯。不存在兩個兩個公司有同樣的公鑰/私鑰對的情況,正是這種區分使得我們可以創建有着相同名稱,版本和語言文化信息的程序集,而不引起任何沖突。
與強命名程序集對應的就是所謂的弱命名程序集。(其實就是普通的沒有被強命名的程序集)。兩種程序集在結構上是相同的。都使用相同的PE文件格式,PE表頭,CLR表頭,元數據,以及清單(manifest)。二者之間真正的區別在於:強命名程序集有一個發布者的公鑰/私鑰對簽名,其中的公鑰/私鑰對唯一的標識了程序集的發布者。利用公鑰/私鑰對,我們可以對程序集進行唯一性識別、實施安全策略和版本控制策略,這種唯一標識程序集的能力使得應用程序在試圖綁定一個強命名程序集時,CLR能夠實施某些“已確知安全”的策略(比如只信任某個公司的程序集)。
三、如何創建強命名程序集, 如何查看強命名程序集的PublicKeyToken
如何創建強命名程序集
===================
1. 在Visual Studio中的class library工程上點右鍵, 選擇properties.
2. 選擇左邊的Signing選項卡.
3. 勾選Sign the assembly復選框. 在下拉列表中選擇<New...>.
4. 在彈出的對話框中給snk文件起一個名字. 按OK.
5. 程序集強命名完成.
如何查看強命名程序集的public key token
=========================
有時候你需要在web.config文件中或者其他地方引用自己寫的強命名程序集, 你需要寫入像下面這樣的fully qualified name:
MyNamespace.MyAssembly, version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
前面三個部分比較容易獲得, 因為是你自己寫的, 你當然知道assembly的名字, 版本, 還有culture信息. 比較麻煩的部分是如何獲得自己簽名的程序集的public key token. 一種平常的方法是使用Reflector來打開自己的程序集, 然后獲得token(實際上, Reflector會給你如同上面例子那樣的完整信息). 但是這有的時候還是顯得有點未免殺雞用牛刀了. 如果你已經打開了Visual Studio, 那么僅僅是在VS的菜單里點一個菜單項就能獲得答案不是更好么? 下面就是步驟.
1. 在Visual Studio中, 打開Tools菜單, 然后點擊External Tools這個菜單項.
2. 在彈出的External Tools對話框中, 點擊Add按鈕.
3. 按照下圖進行配置. sn.exe這個工具在不同版本的VS下處於不同的文件夾中. 最簡單的找到它的方式是在VS Command Prompt中輸入"where sn.exe". 在參數框里寫入"-T $(TargetPath)". 然后勾選"Use Output Window". 這樣的話, 結果就會在VS的output window. 然后點擊OK,
4. 結果如圖.
5. 在輸出窗口可以看到結果. 這在你的solution里有多個project的時候也是可以正常工作的. 只需要點擊一下Solution Explorer中的Project, 然后點擊我們的菜單項就可以了.
四、如何將自己的dll注冊到GAC中
在開發和測試中,最常用的工具就是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)強命名程序集的私有部署
例子:
C:\Program Files\Microsoft Visual Studio 8\VC>gacutil -i F:\myweb\BalloonShop\Cl
assLibrary1\bin\Debug\ClassLibrary1.dll
在C:\WINDOWS\assembly將會看到ClassLibrary1,注冊成功
五、查看GAC文件內容以及將DLL復制出來
在項目中我們常常會引入第三方的dll,一般情況下我們都可以將所需的dll文件復制到硬盤上的一個地方,然后在項目中添加引用,這個操作很簡單!但有時候我們會遇到這樣的情況,就是所要引用的dll在目標機器的GAC里,這時我們就不能手動將它拷貝出來了。
其實Windows的GAC是有對應的目錄的,一般來說為c:\Windows\assembly\,這個目錄有一些特殊,它里面存放的是本機已安裝和注冊的類庫dll,並且不允許用戶直接對其中的元素進行相關操作(如復制、剪切、粘貼、修改名稱等),不過你可以直接將另一位置的dll文件直接拖放到這個目錄下進行dll的安裝,但是我們不能直接將已經安裝進去的dll再拷貝出來。這里我將介紹一種方法來完成這個操作。
首先我們切換到Windows的命令行方式,即開始-運行-cmd-回車,然后轉到GAC所在的目錄,利用dir命令查看一下其中的內容,如下圖。
似乎可以明白GAC中的目錄結構了,基本上我們可以根據GAC目錄中的Processor Architecture列來區分dir的類型,例如我們要找的System.Web.Extensions屬於MSIL,在CMD方式下它應該就對應GAC_MSIL,然后切換到這個目錄下並dir。
看到我們要找的System.Web.Extensions程序集了,它也是一個dir,繼續切進去並dir。
這時只有一個目錄了,繼續切進去,然后dir就可以看到我們最終想要的dll文件了,然后通過copy命令將它復制出來就OK了!
小技巧:在CMD方式下使用命令時,如果要輸入的文件名或目錄名太長,可以先敲部分字符,然后通過Tab鍵自動補全,Windows的command工具會自動為你找到相匹配的內容!
六、例子
如上圖所示,新建了2個類庫文件:ClassLibrary1、ClassLibrary2
1、使用上面的第三點創建了強類型程序集ClassLibrary1,並且注冊到GAC中(可以使用上面第三點的方法,也可以使用反編譯器進行反編譯,可以查看到PublicKeyToken值。ClassLibrary2為null,ClassLibrary1為568e03e6162a7a2e)。
2、在DataAccess中引用ClassLibrary1、ClassLibrary2,編譯DataAccess。
3、進入DataAccess工程的bin\debug文件夾下,只有ClassLibrary2.dll與DataAccess.dll(沒有ClassLibrary1.dll)
由此可知:程序是從GAC中直接取得ClassLibrary1.dll的而不是從ClassLibrary1工程中將ClassLibrary1.dll拷貝到自身的debug中進行引用。