日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

NET程序集強簽名收藏 強名稱工具 (Sn.exe) 來創

系統 2281 0

強名稱是由程序集的標識加上公鑰和數字簽名組成的。其中,程序集的標識包括簡單文本名稱、版本號和區域性信息(如果提供的話)。強名稱是使用相應的 私鑰,通過程序集文件(包含程序集清單的文件,并因而也包含構成該程序集的所有文件的名稱和散列)生成的。Microsoft? Visual Studio? .NET 和在 .NET Framework SDK 中提供的其他開發工具能夠將強名稱分配給一個程序集。強名稱相同的程序集應該是相同的。

通過簽發具有強名稱的程序集,您可以確保名稱的全局唯一性。強名稱還特別滿足以下要求:

  • 強名稱依賴于唯一的密鑰對來確保名稱的唯一性。任何人都不會生成與您生成的相同的程序集名稱,因為用一個私鑰生成的程序集的名稱與用其他私鑰生成的程序集的名稱不相同。

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

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

在引用具有強名稱的程序集時,您應該能夠從中受益,例如版本控制和命名保護。如果此具有強名稱的程序集以后引用了具有簡單名稱的程序集(后者沒有這 些好處),則您將失去使用具有強名稱的程序集所帶來的好處,并依舊會產生 DLL 沖突。因此,具有強名稱的程序集只能引用其他具有強名稱的程序集。

使用程序集和全局程序集緩存

如果您需要在幾個應用程序間共享程序集,可將其安裝到全局程序集緩存中。安裝了公共語言運行庫的每臺計算機均具有此計算機范圍的代碼緩存。全局程序集緩存中存儲了專門指定給由計算機中若干應用程序共享的程序集。要安裝到全局程序集緩存中,程序集必須具有強名稱。

注意

全局程序集緩存中放置的程序集必須具有相同的程序集名稱和文件名(不包括文件擴展名)。例如,程序集名稱為 myAssembly 的程序集必須具有名為 myAssembly.exe 或 myAssembly.dll 的文件。

應當只在必要時才將程序集安裝到全局程序集緩存中來共享程序集。一般原則是:程序集依賴項保持專用,并在應用程序目錄中定位程序集,除非明確要求共享程序集。另外,您不必為了使 COM interop 或非托管代碼可以訪問程序集而將程序集安裝到全局程序集緩存。

要將程序集安裝到全局程序集緩存中的原因有以下幾點:

  • 共享位置。

    可將應用程序應該使用的程序集放在全局程序集緩存中。例如,如果所有的應用程序都應使用位于全局程序集緩存中的程序集,則可將版本策略語句添加到 Machine.config 文件(此文件將引用重新定向到程序集)。

  • 文件安全性。

    管理員通常使用訪問控制列表 (ACL) 來保護 systemroot 目錄,以控制寫入和執行訪問。因為全局程序集緩存安裝在 systemroot 目錄中,它繼承了該目錄的 ACL。建議只允許具有“管理員”權限的用戶從全局程序集緩存中刪除文件。

  • 并行版本控制。

    可在全局程序集緩存中維護程序集的多個副本(名稱相同但版本信息不同)。

  • 其他搜索位置。

    在探測或使用配置文件中的基本代碼信息之前,公共語言運行庫會先檢查全局程序集緩存中符合程序集請求的程序集。

請注意,在有些情況下,您肯定不需要將程序集安裝到全局程序集緩存中。如果將組成應用程序的某個程序集放在全局程序集緩存中,就無法再通過使用 XCOPY 復制應用程序目錄來復制或安裝應用程序。在這種情況下,還必須將程序集移到全局程序集緩存中。

全局程序集緩存

要使用 Visual Studio .NET 創建小型類庫項目、生成強名稱,以及在 GAC 中安裝項目的 .dll 文件,請按照下列步驟操作:

1. 在 Visual Studio .NET 中,創建一個新 Visual C# .NET 類庫項目,并將該項目命名為 GACDemo
2. 必須使用強名稱。要生成此加密密鑰對,請使用 SN 工具。此工具位于安裝 .NET Framework 解決方案開發人員工具包 (SDK) 的 \bin 子目錄中。SN 工具易于使用。命令行語句采用以下形式:
sn -k "[DriveLetter]:\[DirectoryToPlaceKey]\[KeyName].snk"
3. 在 C:\ 中創建一個名為 GACKey 的目錄,以便您可以輕松地找到密鑰,并從命令提示符處訪問該密鑰。

注意 : 對于大多數用戶,.NET 工具位于 C:\Program Files\Microsoft.NET\FrameworkSDK\Bin 中。鍵入以下 SN 命令前,可能需要在您的計算機上將與該路徑類似的路徑復制到 .NET bin 目錄中。從命令提示符處鍵入 cd ,右鍵單擊以粘貼該路徑,然后按 Enter,快速轉至 SN 工具所在的目錄。

鍵入以下內容:
sn -k "C:\GACKey\GACkey.snk"
4. 將生成一個密鑰,但是它與項目的程序集尚無關聯。要建立此關聯,請在 Visual Studio .NET 解決方案資源管理器中雙擊 AssemblyInfo.cs 文件。此文件具有一個程序集屬性列表,默認情況下,在 Visual Studio .NET 中創建項目時將包括這些屬性。在代碼中修改“AssemblyKeyFile”程序集屬性,如下所示:
[ assembly:AssemblyKeyFile("C:\\GACKey\\GACKey.snk") ]
通過按 Ctrl+Shift+B 來編譯項目。您不必具有任何附加代碼即可以在 GAC 中安裝 .dll 文件。
5. 您可以通過使用 Gacutil 工具或者通過將 .dll 文件拖至適當的目錄來安裝 .dll 文件。如果您使用 Gacutil 工具,則可以使用以下命令:
gacutil -I "[DriveLetter]:\[PathToBinDirectoryInVSProject]\gac.dll"
如果您要拖動文件,請使用 Microsoft Windows 資源管理器。打開 Windows 資源管理器的兩個實例。在一個實例中,找到控制臺項目的 .dll 文件輸出的位置。在另一實例中,找到 c:\[SystemRoot]\Assembly。

將您的 .dll 文件拖到“Assembly”文件夾中。

用強名稱來給程序集簽名即謂之程序集強簽名!

那什么是強名稱,簽名又有什么作用?,我們先看看強名稱的概念是什么,強名稱是由程序集的標識加上公鑰和數字簽名組成的,其中程序集的標識包括簡單文本名稱,版本號和區域性信息!

Visual Studio.NET 和 .NET Framework SDK 中有工具能夠將強名稱分配給一個程序集!強名稱相同的程序集一般也是相同的!

好了,具體我們可以通過給程序集強簽名達到什么目的呢?

通過簽發具有強簽名的程序集合,可以確保名稱的全局唯一性!因為強名稱是依賴于唯一的密鑰對來確保名稱的唯一性,其他人不會生成與你相同的程序集名稱(不同的私鑰產生的名稱不同)

強名稱保護程序集的版本沿襲,因為強名稱的唯一性能夠確保沒有其他人能夠生成你的程序集的后續版本

強名稱提供可靠的完整性檢查,通過.NET Framework安全檢查后,可以確保程序集內容在生成后未被更改過!

要注意的是,具有強名稱的程序集引用其他程序集,如果這個程序集沒有強名稱,那么具有強名稱的程序集所帶來的好處,并依舊會產生DLL沖突!因此具有強名稱的程序集只能引用其他具有強名稱的程序集。

強命名程序集(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能夠實施某些“已確知安全”的策略(比如只信任某個公司的程序集)。

How:實現.NET Strong Named(強簽名)防止程序被篡改

對.Net Assembly來說, 通過反射(Reflection)機制,得到一個Assembly里面所有的函數簽名是很簡單的.因此大家都可以制作一個和原Assembly具有完全一 樣接口的Assembly來讓系統或者應用程序調用,這為dll hell提供了極大的便利。顯然,.Net需要提供一種機制來防止這樣的事情,尤其當我們從網上更新Assembly的時候,我們如何相信當前得到 Assembly就是合法的那個呢? 一種辦法是讓Assembly的最初發布者提供簽名,程序只相信具有同樣簽名的Assembly,而且除了作者,別人不能生成這個簽名。.Net Runtime提供的就是這樣一個機制。

首先我們看一下.Net Runtime是怎么識別和導入一個DLL的。在.Net中當我們說Assembly Name的時候,不是僅僅指其文件名(比如abc.dll)。實際 上,Assembly name是由四個部分構成的:Friendly Name,Culture, Pubilc Key(Token), Version。除了Friendly Name 和 Version 是一定有的,其他兩個取決于開發者有沒有指定它們。比如像我這樣的初學者就不會去做一個有Public Key的程序,如果沒有指定的話,Culture=neutral,PublicKeyToken=null。本文忽略Culture和Version對 識別和導入一個DLL的影響,因為那是另一篇文章。我們知道,Assembly 導入有顯示導入和隱式導入兩種。顯示指的是使用Assembly.Load或者Assembly.LoadFrom來動態導入一個Assembly到內存 當中。隱式指的是CLR自動導入所要用到的Assembly(和我原先理解的不同的是,CLR并不是在在程序一開始運行就導入所有Reference的 Assembly,而是當一個數據類型被用到的時候,再去解析和導入對應的Assembly)當CLR Loader決定導入一個Assembly的時候,它一定會導入和Reference階段具有相同PublicKey或者PublicKeyToken的 Assembly。否則導入失敗。比如我們在Reference的abc Assembly的PublicKeyToken是1234123412341234,那么在運行階段,它就會去找具有 1234123412341234PublicToken的Assembly,找不到便拋出異常。當然如果Reference的Assembly不具備 Publickey,.Net Runtime 就會省略這個過程,由此,我們可以看出Pulic Key或者PublicKeyToken就是我們需要的數字簽名。我們將具有Public Key的程序稱之為強簽名程序。

那么到底什么是PublicKey和PublicKeyToken?
Public Key沒啥神秘,我們可以把它當成是128byte的數據加上32byte的頭信息。它標識了一個Assembly的開發者。如果每次去 Reference或者Load一個Assembly都需要輸入這160字節的字符,未免太繁瑣,于是我們可以用SHA 哈希算法(關于SHA標準,大家可以自己google一下)生成(我們不需要自己做,.Net SDK提供了這樣的工具,下文會講到)一個只有8個字節的PublicKeyToken,每次用這個PublickKeyToken就可以讓.Net Compiler或者Loader找到相應的Assembly了。比如很多.Net自帶的系統庫,它的PublicKeyToken一般就是 b77a5c561934e089,如果你用VisualStudio開發,你不需要指明這個,因為編譯器對待系統庫,會默認用這個 PublicKeyToken。
擁有PubickKey并不能保證你的Assembly不被別人盜版使用,但是可以保證你的Assembly不被別人冒充。也就是別人不能生成和你有同樣Publickey的Assembly。
原 來在生成強簽名的Assembly的時候,PublicKey和Private Key要一起使用,是不是似曾相識呢,原來就是網絡傳輸中的RSA公鑰算法(關于RSA公鑰算法,大家可以自己google一下)。Private Key可以當成是436字節的數據(字符串),Assembly的PublicKey是Assembly的使用者都可以得到的,但是PrivateKey 就只有作者知道了。如果你是在一個很大的團隊里開發一個很大的項目,恐怕你自己都不知道你開發的Asembly的Private Key(一般只有發布官才知道)。那么如果連程序員自己都不知道,他怎么調試他的Assembly呢?下文會介紹。

說了這么多理論,現在來看看具體怎么開發和部署具備Strong Name的Assembly吧,.Net SDK已經為我們提供了一個非常好的工具Sn.exe. 下面就Step by Step吧,

1. 產生一個試驗性的Assembly,隨便寫點代碼,用Visual Studio Class Library模板生成一個Assembly就叫 test.dll 吧. 代碼如下:
namespace Test
{
public class Class1
{
public string A()
{
return "This is test App";
}
}
}

2.寫一個Console程序,Reference test.dll,調用A(),如下,
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Test.Class1 c = new Test.Class1();
Console.WriteLine(c.A());
}
}
}

程序輸出:This is test App;

3.現在因為Test.dll不是Strong name的dll,任何人都可以冒用你的名義也生成一個test.dll,并且在#2的程序路徑下替換原來那個,代碼如下:
namespace Test
{
public class Class1
{
public string A()
{
return "This is a hack app";
}
}
}
現在運行以下#2中的程序,運行輸出This is a hack app。
4. 用Sn.exe 生成一個Public/Private Key Pair 文件:Sn -k test.snk. 如果不指定大小,它的大小就是596 bytes(128 publicKey,32 publicKey Header, 436 PrivateKey)
5. 添加 [assembly: AssemblyKeyFile(@"..\..\test.snk")]到程序的AssemblyInfo.cs中,也可以在Build Option中指定(/keyfile:test.snk ). 再重新生成test.dll. 在VisualStudio中還可以用工程屬性指定
6. Sn -v test.dll 查一下test.dll是不是已經是一個strongname的程序了,輸出:test.dll is valid。表示成功生成了一個具有PublicKey的程序 Sn -T test.dll 可以得到這個assembly的PublickKeyToken。
7. 用#2的程序重新引用新生成的test.dll, 重新編譯#2的console程序。
8. 重復#3,現在程序運行失敗了。因為它找不到具有相應PublicKey的test.dll.

9. 如果我是一個大項目的發布者,我不想讓團隊的所有開發者都知道privatekey file,那么應該使用 sn -p test.snk publickonly.snk, 生成一個只有Publick Key的文件,并讓團隊開發者暫時使用Publickonly.snk來給程序簽名,并把test.snk藏起來,打死也不說。
10. 開發者拿到這有PublicKey的snk文件以后,他除了要做#5之外,還需要加上[assembly: AssemblyDelaySign(true)]. (也可以通過BuildOption指定),不然不能成功build。這樣生成出來的Assembly便預留來空白位置,讓日后發布時可以用 Sn -R test.dll test.snk重新簽名。
11. 這個時候讓#2重新引用新的test.dll 生成程序,運行#2還是會失敗。因為Test.dll畢竟是一個沒有用Private Key 簽名的假的strong name Assembly.
12. 開發者想要啟動#2 Debug test.dll, 那么還需要做 Sn -Vr test.dll 告訴Runtime我知道并認可這是一個臨時簽名的文件,讓它運行吧。
13. 在發布前,發布官運行 sn -R test.dll test.snk 重新簽名,就可以發布了。

強名稱工具 (Sn.exe) 來創建密鑰對:

要使用強名稱為程序集簽名,必須具有公鑰/私鑰對。這一對加密公鑰和加密私鑰用于在編譯過程中創建強名稱程序集。您可以使用強名稱工具 (Sn.exe) 來創建密鑰對。密鑰對文件通常具有 .snk 擴展名。

創建密鑰對

  • 在命令提示處,鍵入下列命令:

    sn –k <file name>

    在此命令中,“文件名”是包含密鑰對的輸出文件的名稱。

下面的示例創建名為 sgKey.snk 的密鑰對。



                sn -k sgKey.snk
              

如果您需要延遲對程序集簽名并控制整個密鑰對(密鑰對不太可能在測試方案之外),可使用以下命令生成密鑰對,然后從中將公鑰提取到一個單獨的文件中。首先,創建密鑰對:


                sn -k keypair.snk
              
  • 下一步,從密鑰對中提取公鑰,并將其復制到一個單獨的文件中:


                sn -p keypair.snk public.snk
              
  • 創建密鑰對之后,必須將文件放在強名稱簽名工具可以找到的位置。

當使用強名稱對程序集進行簽名時,程序集鏈接器 (Al.exe) 查找與當前目錄和輸出目錄相關的密鑰文件。當使用命令行編譯器時,只需將密鑰復制到包含代碼模塊的當前目錄即可。

如果要使用 IDE(例如 Visual Studio 2005)為程序集簽署強名稱,則必須知道 IDE 查找密鑰文件的位置。例如, C# 編譯器則在包含二進制文件的目錄下查找密鑰文件。將密鑰文件放在適當的項目目錄中并設置文件屬性,如下所示:



C#



            [assembly: AssemblyKeyFileAttribute(@"..\..\key.snk")]
          

NET程序集強簽名收藏 強名稱工具 (Sn.exe) 來創建密鑰對:


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 太康县| 广德县| 华坪县| 乐都县| 平和县| 资中县| 会东县| 航空| 祁连县| 五莲县| 云梦县| 和静县| 安塞县| 达日县| 福鼎市| 禹城市| 梅州市| 合江县| 定结县| 平昌县| 阳高县| 修武县| 卢氏县| 兴国县| 台东县| 安义县| 柳江县| 隆回县| 浦县| 榆林市| 伊川县| 宁远县| 乌拉特中旗| 祁连县| 岳普湖县| 上饶县| 伊吾县| 平远县| 双峰县| 双流县| 楚雄市|