標籤:
強式名稱簽名的方法:
強簽名:
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
分類: C#/Net
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中進行引用。
C#程式集使用強名字(Strong Name)簽名/強式名稱簽名