[轉]clr 強命名程序集和共享程序集

 

3.1    兩種程序集,兩種部署
    CLR有兩種程序集,弱命名程序集和強命名程序集,二者基本一樣,區別:強命名程序集時用發佈者的公鑰/私鑰對 進行了簽名,唯一性的標識了程序集的發佈者。弱命名程序集只能私有部署,強命名程序集可以使用全局部署,也可以私有部署。
    
3.2    爲程序集指派強名稱
    一個強命名的程序集包括4部分重要屬性,標誌唯一:一個無擴展名的程序集,一個版本號,一個語言文化標誌,一個公鑰publickey。此外,還使用發佈者的私鑰進行簽名
        MyTypes,Version=1.0.8123.0,Culture=neatral,PublicKeyToken=xxxxxxxxxxxxxxxx(公鑰標記)

    MS使用公鑰/私鑰加密技術,這樣,沒有兩家公司有相同的公鑰/私鑰對(除非他們共享公鑰/私鑰對)。
    
    使用反射獲取強命名程序集的PublicKeyToken

    創建強命名程序集的步驟:
        1.生成公鑰/私鑰對:使用SN命令,這個命令所有開關都區分大小寫
            SN    -k    MyCompany.keys
            ——這裏MyCompany.keys是創建的文件名

        2.將原有程序集升級爲強命名程序集
            csc    /keyfile:MyCompany.keys    app.cs
            ——這裏,app.cs是包含清單表的文件,不能對不包含清單表的文件簽名。C#編譯器會打開MyCompany,使用私鑰對程序集進行簽名,並在清單中嵌入公鑰。           

用私鑰簽名一個文件:是指生成一個強命名程序集時,程序集的FileDef清單中列出了包含的所有本件,將每個文件名稱添加到清單中,文件的內容都會根據私鑰進行哈希處理,得到的哈希值與文件名一起存入FileDef中。這個哈希值稱爲RSA數字簽名。

最終,生成的包含清單的PE32文件,其中會含有RSA數字簽名和公鑰

補充1:簽名默認使用SHA-1算法,也可以使用別的算法,通過AL命令的/algid開關指定。
     
補充2,還可以使用SN命令,在原有基礎上,得到只含公鑰的文件並顯示:
            SN    -p    MyCompany.keys    MyCompany.PublicKey
            ——這裏MyCompany.PublicKey是創建的公鑰文件名
            SN    -pt   MyCompany.PublicKey
            ——顯示公鑰與公鑰標記   

補充3:在IL中,Local對應於Culture

補充4:公鑰標記是公鑰的最後8個字節。
              AssemblyRef中存的是公鑰標記,AssemblyDef存的是公鑰。

3.3    GAC 全局程序集緩存
    GAC一般在C:\Windows\Assembly,結構化的,有很多子目錄。
        使用Windows Explorer shell擴展來瀏覽GAC目錄,這個工具是在安裝Framework時附帶的。
        不能使用手動方法複製程序集文件到GAC,要使用GACUtil命令。
        只能安裝強命名程序集到GAC中,而且要有Admin/PowerUser權限。
    
    GAC的好處是可以容納一個程序集的多個版本。每個版本都有自己的目錄。缺點是違反了簡單安裝的原則。

3.4    在生成的程序集中引用一個強命名程序集    
第2章有講到,對於不完整路徑,csc編譯時目錄查找順序:
    1.工作目錄(要編譯的cs文件所在)
    2.系統目錄(csc.exe所在,同時也包括CLR DLL)
    3./lib開關指定的目錄
    4.LIB系統變量指定的目錄

安裝Framework時,會安裝.NET程序集兩套副本,一套在編譯器/CLR目錄——便於生成程序集,另一套在GAC子目錄——便於在運行時加載它們。編譯時並不去GAC中查找。

3.5    強命名程序集能防範篡改
在安裝強命名程序集到GAC時,系統對包含清單的文件內容進行哈希處理,並將這個值與PE32文件中嵌入的RSA數字簽名進行比較,如果一致,就再去比較其他文件內容(也是哈希處理在比RSA簽名)。一旦有一個不一致,就不能安裝到GAC。

如果強命名程序集安裝在GAC以外的目錄,則會在加載時比較簽名。

3.6    延遲簽名(部分簽名)   delayed signing
開發階段會使用到這個功能
允許開發人員只用公鑰來生成一個程序集,而不需要私鑰。
編譯時,會預留一定空間來存儲RSA數字簽名,不對文件內容進行哈希處理。CLR會跳過對哈希值的檢查。以後可
以再對其進行簽名。
步驟如下:
1.生成程序集:csc /keyfile: MyCompany.PublicKey /delaysign: MyAssembly.cs
2.跳過對哈希值的檢查: SN.exe -Vr MyAssembly.dll
3.準備私鑰,再次進行簽名:    SN.exe -R MyAssembly.dll MyCompany.PrivateKey
4.再次延遲簽名:    SN.exe -Vu MyAssembly.dll

3.7    私有部署強命名程序集
強命名程序集如果不在GAC中,每次加載都要進行驗證,有性能損失。
還可以設計爲局部共享強命名程序集,指定配置文件的codeBase即可。

3.8    運行庫如何解析類型引用
    在TypeRef中查找類型引用的紀錄,發現其強簽名,然後定位這個程序集的所在位置:會在以下三個地方查找:
        1.同一個文件:編譯時就能發現(早期綁定)
        2.不同的文件,但同一個程序集:在FileRef表中
        3.不同的文件,不同的程序集:這時要加載被引用的程序集,從中查找

注:AssemblyRef使用不帶擴展名的文件名來引用程序集。綁定程序集時,系統通過探測xx.dll和xx.exe來定位文件。
        ModuleDef,ModuleRef,FileDef使用文件名及其擴展名來引用文件。

注:在GAC中查找程序集時,除了名稱,版本,語言文化和公鑰,還需要CPU體系結構,而且是先根據這個體系結構查找

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章