關於強命名

 

因爲最近換了一家公司工做,去的次日就開始作項目,就在本身的項目去引用其餘項目時,而後編譯,卻報「程序集生成失敗 -- 引用的程序集沒有強名稱」的錯誤。緣由:本身的項目是強命名程序集,強命名程序集不能引用普通程序集形成的。這時候,想起來曾經也碰到過這樣的問題,因此解決起來也比較簡單。今天拿出來寫寫,主要是想讓曾經碰到一樣問題的人一個解決問題的思路,僅此而已。若說的很差,還望你們批評指導。html

    在解決這個問題以前,我想說說強簽名程序集的概念以及由來,這樣對咱們解決問題的時候,知道問題一些本質東西。git

  1、什麼叫強命名程序集?算法

    咱們知道,之前在Windows下開發程序時常會遭遇著名的「DLL Hell」問題(兩個不一樣的公司可能開發處具備相同名稱的程序集,若是將相同名稱的程序集放置到同一個目錄下,則會出現程序集覆蓋現象,最後安裝的程序集會覆蓋前面的程序集,從而可能致使應用序不能正常運行,由此看來,僅靠名稱來區分程序集是不足夠的。),即動態連接庫的向後兼容問題。微軟在.Net產生前曾嘗試使用COM組件的方式來解決DLL Hell問題,即便用Guid來惟一的標識每個COM組件。可是,實際上使用COM組件(包括版本升級)也是一件頗爲麻煩的事:爲了運行COM組件就必須在組冊表中對其進行註冊,從新編譯有可能破壞Guid從而致使原來引用此COM組件的程序不能正確運行等等。緩存

    在.Net中,微軟引入了一種新的解決方案:強命名程序集(Strong Name),以及與之配套的全局程序集緩存(GAC)來解決這個問題。安全

 .Net支持兩種程序集:弱命名程序集和強命名程序集(注:.Net框架中沒有弱命名程序集,只是爲了和強命名程序集相對應而已)。 弱命名程序集和強命名程序集在結構上是相同的。他們都採用PE文件格式,包含PE表頭,CLR表頭,元數據和清單表。 區別在於:強命名程序集擁有一個發佈者的公鑰/私鑰簽名對,他們用於惟一的標識程序集的發佈者。經過公鑰/私鑰對,咱們能夠對程序集進行惟一的標識,安全策略和版本策略。 強名稱主要用處:就是防止dll被隨意引用,另外控制版本,標識惟一性。app

    在.NET中,強命名程序集應包含四個標識:Name(名稱)、Version(版本號)、Culture(語言文化標識)、PublicToken(共有/私有密鑰對),使用它們來惟一標識一個程序集,框架

而不一樣產品前三個屬性(Name、Version和Culture)徹底相同的狀況是有可能發生的,如此一來,這惟一標識程序集可重任就落到PublicToken的頭上了。強命名的程序集正是使用RSA來保證PublicToken的惟一性,由於在理論上,非對稱算法RSA生成的公鑰/私鑰對不會重複。.Net正是經過在編譯項目時將指定的公鑰/私鑰對寫入程序集來保證其惟一性。ide

     對於全局程序集緩存(GAC),安裝有公共語言運行庫的每臺計算機都具備稱爲全局程序集緩存的計算機範圍內的代碼緩存。全局程序集緩存中存儲了專門指定給由計算機中若干應用程序共享的程序集。工具

    在開發通常的、非共享的程序時,咱們不須要使用強命名的程序集,僅將項目(Project)編輯成.DLL或者.EXE便可。可是,若是咱們開發的是組件庫、框架時,經過對程序集進行強命名,並使用將其部署到GAC中,能夠保證咱們的程序集不會出現版本問題。ui

   2、建立強命名程序集方法

    須要使用SN工具來生成密鑰對。該工具位於安裝.NET Framework SDK的Bin目錄中,在命令行(visual studio 2005/2008/2010命令提示(開始-->程序-->microsoft visual studio 2005-->visual studio  tools-->visual studio 2005命令提示))中使用「 SN -k [驅動器號]:[放置密鑰的目錄][密鑰名稱].snk 」這樣的語句能夠生成密鑰對文件。例如,SN -k d:\MKeyStudio.snk,就會生成名爲MKeyStudio.snk的密鑰對文件,且存儲在D盤根目錄下。那如何讓該密鑰文件與項目的程序集創建關聯呢?咱們須要打開項目(Project)的AssemblyInfo.cs 文件,此文件具備一個程序集屬性列表,默認狀況下,在Visual Studio .NET 中建立項目時將包括這些屬性。在代碼中增長名爲「AssemblyKeyFile」的屬性,形式以下:[assembly:AssemblyKeyFile("d:\MKeyStudio.snk")]   。此時,編譯該項目即生成強命名的程序集項目。若MKeyStudio.snk文件在該項目的根目錄(即與該項目解決方案文件處於同一個目錄)下,則此時須要修改AssembleyInfo.cs文件中的「AssemblyKeyFile」屬性,形式以下:[assembly:AssemblyKeyFile("MKeyStudio.snk")]。此方法是經過給程序集清單文件添加「AssemblyKeyFile」屬性來實現強名稱。還能夠經過,右擊該項目,出現下拉菜單,選擇「屬相」,打開「簽名」Tab,勾上「爲程序集簽名」複選框,以後就能夠選擇一個強名稱密鑰文件做爲該項目的簽名就ok了。

(出處:http://hi.baidu.com/jack1865/item/d14e4c94574d869ecc80e557

強命名程序集(Strong Name 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可以實施某些「已確知安全」的策略(好比只信任某個公司的程序集)。

(出處:http://www.baike.com/wiki/%E5%BC%BA%E5%91%BD%E5%90%8D

強名稱是由程序集的標識加上公鑰和數字簽名組成的。其中,程序集的標識包括簡單文本名稱、版本號和區域性信息(若是提供的話)。  強名稱是使用相應的私鑰,經過程序集文件(包含程序集清單的文件,並於是也包含構成該程序集的全部文件的名稱和散列)生成的。  Visual Studio 能夠爲程序集分配強名稱。  強名稱相同的程序集應該是相同的。 

經過簽發具備強名稱的程序集,你能夠確保名稱的全局惟一性。   強名稱還特別知足如下要求: 

  • 強名稱依賴於惟一的密鑰對來確保名稱的惟一性。   任何人都不會生成與你生成的相同的程序集名稱,由於用一個私鑰生成的程序集的名稱與用其餘私鑰生成的程序集的名稱不相同。 

  • 強名稱保護程序集的版本沿襲。強名稱能夠確保沒有人可以生成你的程序集的後續版本。  用戶能夠確信,他們所加載的程序集的版本出自建立該版本(應用程序是用該版本生成的)的同一個發行者。 

  • 強名稱提供可靠的完整性檢查。   經過 .NET Framework 安全檢查後,便可確信程序集的內容在生成後未被更改過。  但請注意,強名稱中或強名稱自己並不暗含信任級別,例如由數字簽名和支持證書提供的信任。 

在引用具備強名稱的程序集時,你應該可以從中受益,例如版本控制和命名保護。    若是此具備強名稱的程序集之後引用了具備簡單名稱的程序集(後者沒有這些好處),則你將失去使用具備強名稱的程序集所帶來的好處,並依舊會產生 DLL 衝突。  所以,具備強名稱的程序集只能引用其餘具備強名稱的程序集。

(出處:http://msdn.microsoft.com/zh-cn/library/wd40t7ad(v=vs.110).aspx 

改進的強命名:http://msdn.microsoft.com/zh-cn/library/hh415055(v=vs.110).aspx

相關文章
相關標籤/搜索