為何使用強名稱,publickeytoken的作用

2021-04-13 08:48:01 字數 3450 閱讀 8712

概念:

(一)dotnet中的版本組成

dotnet中的版本由4個物理號碼組成,如圖(一) 

圖(一)

在程式集裡面,我們可以通過加上assemblyversion特性來設定它,

如[assembly: assemblyversion("2.0.2.11")]

(二) gac:

計算機範圍內的**快取,它儲存專門安裝的程式集,這些程式集由計算機上的許多應用程式共享。在全域性程式集快取中部署的應用程式必須具有強名稱,乙個程式集如果註冊到了gac裡,被其他程式集合引用的時候,將不會拷貝副本到引用的程式目錄中。 (本文只討論註冊到gac中的程式集)

正文:(1) 我們現在開始寫第乙個元件

它的版本號為 1.0.0.0 有乙個類,包含乙個簡單的方法,該方法返回乙個字串

**如下,我都做了註解

//首先生成強名稱到檔案中

sn –k c:/version.snk

//寫類檔案

v1.cs

using

system;

using

system.reflection;

[assembly: assemblykeyfile(

@"c:version.snk

")]  

//因為註冊到gac,所以使用強名稱簽名

[assembly: assemblyversion(

"1.0.0.0

")]   

//設定版本號

namespace

v1public

string

getversion()}}

編譯成元件 v1.dll

拷貝這個v1.dll到 資料夾c:/v1

把v1.dll註冊到gac

gacutil –i c:/v1/v1.dll

系統顯示註冊成功

(2) 然後我們編寫乙個控制台程式測試這個元件

testversion.cs

//////

請新增對v1.dll(c:v1v1.dll)的引用,因為是在gac裡面,所以v1.dll不會在本地目錄存在

///using

system;

namespace

testversion}}

編譯後執行(testversion.exe)

螢幕輸出的結果是 :

"你好,我是版本1"

(3) 好了,一切很美好,過了幾年了,我們得公升級程式了

現在來編寫v1.dll公升級版本,版本號為2.0.0.0

v1.cs

using

system;

using

system.reflection;

[assembly: assemblykeyfile(

@"c:version.snk

")] 

///使用上面的強名稱

[assembly: assemblyversion(

"2.0.0.0

")] 

///注意,這裡已經改了主版本號

namespace

v1public

string

getversion()}}

編譯 成元件 v1.dll

拷貝這個v1.dll到 資料夾c:/v2

把v1.dll註冊到gac

gacutil –i c:/v2/v1.dll

(4) .現在來看看再次執行testversion.exe輸出了什麼東西

是的,和原來的沒有變化還是

"你好,我是版本1"

為什麼不是"你好,我是版本2"?

我們用ilda**.exe開啟程式集testversion.exe 看看

是的,它目前就是使用了版本1.0.0.0

(5) 我們開始進行版本公升級

把testversion.exe使用的版本由1.0.0.0替換成版本2.0.0.0

其實很簡單的,給我們的 testversion.exe

加個配置檔案 testversion.exe.config裡面打入

<?

xml version="

1.0"

?>

<

configuration

>

<

runtime

>

<

assemblybinding xmlns="

urn:schemas-microsoft-com:a**.v1

">

<

dependentassembly

>

<

assemblyidentity name="

v1"publickeytoken="

758fe4e9db9d8251

"/>

<

bindingredirect oldversion="

1.0.0.0

"newversion="

2.0.0.0

"/>

dependentassembly

>

assemblybinding

>

runtime

>

configuration

>

簡單說明:

assemblyidentity 主要進行程式集合的標識

其中 name是程式集的名稱 publickeytoken是公匙的標記;如何獲得這些資訊呢?很簡單,開啟%systemdir%/assembly (我的是c:/winnt/assembly)

可以看到這些資訊(如下圖,你的機器上可能和我不一樣)

可以看到有兩個v1(正確,我們確實註冊了兩個進去,版本也對) 我們開始用的是1.0.0.0的,記下公匙token 寫到publickeytoken

bindingredirect 節點主要配置版本如何跳轉

oldversion="1.0.0.0" newversion="2.0.0.0" 很清楚的,就是如果testversion.exe使用的v1.dll是舊版本的,程式集版本號為1.0.0.0,那麼就使用新的,版本號為2.0.0.0的程式集

需要注意的是,oldversion 可以使用範圍來界定,如 oldversion="1.0-1.9" 但是如果沒有使用範圍表示法的話,一定要寫全版本號

newversion 不可以使用範圍表示法,請寫全版本號

好了,現在再次執行testversion.exe

輸出的是: "你好,我是版本2",掌聲!!!

就是怎麼簡單!

(6) 如果現在我們用ilda**.exe開啟程式集testversion.exe,看到的內容將沒有變化

確實,是配置檔案起了作用,整個過程沒有對呼叫程式testversion.exe的**做半點改動!

(7) 配置錯了會怎麼樣?:

有可能的錯誤,比如newversion寫錯了,根本沒這個公升級版本,將會丟擲異常system.io.filenotfoundexception,請注意處理

強名稱保護

用 籤強名稱我會 中 sn k key.snk csc keyfile key.snk cs 強名稱的去除 頭中的flag項,去除comimage flags strongnamesigned標誌 頭中的strongnamesignature,與 為 表中的 項,送去0 0001 標識 通常變後為0...

強名稱(3)強名稱的脆弱性

通過前文共同體驗了強名稱對程式集的保護方式和原理,但是這種保護的強度到底有多大呢?能有效地防禦惡意篡改者嗎?先看下面的例子。回到上篇文章的 清單 9 7,重新對 strongnamereferencelib 專案進行強名稱簽名,然後編譯 strongname 專案。在 strongname 專案的b...

強名稱程式集不能引用非強名稱程式集

想生成乙個強名稱程式集,引用了乙個非強名稱程式集裡的型別,結果在編譯時出錯 error cs1577 程式集生成失敗 引用的程式集 mytypes 沒有強名稱 檢視msdn中編號為cs1577的編譯器錯誤,顯示如下資訊 程式集生成失敗 原因 編譯的程式集生成部分失敗。有關更多資訊,請參見 alink...