• 共享程序集和强命名程序集


    两种程序集,两种部署


      CLR支持两种类型的程序集:弱命名程序集(weakly named assembly)和强命名程序集(strongly named assembly)。二者的区别:强命名程序集使用发布者的公钥/私钥进行了签名。这一堆密钥允许对程序集进行唯一性的标识、保护和版本控制。

      程序集可采用两种方式部署:私有或全局。私有部署的程序集是指部署到应用程序基目录或子目录的程序集,弱命名程序集只能以私有方式部署。全局部署的程序集是指部署到一些公认位置的程序集(GAC),CLR在查找程序集时,会检查这些位置,强命名程序集既可以私有部署,也可以全局部署。

    为程序集分配强名称


      强命名程序集有4个重要特性:文件名、版本号、语言文化和公钥(由于公钥数字很大,所以通常使用从公钥派生的小哈希值,称为公钥标记)。以下是一个强命名程序集标识字符串及说明:

    如何使用Visual Studio创建密钥文件以及强命名程序集这里就不介绍了,Properties|Signing|Sign the assembly,下面介绍使用强命名工具sn.exe以及C#命令行编译器csc.exe生成强命名程序集

    创建强命名程序集

    1. 使用强命名工具sn.exe创建密钥文件。

       sn.exe位置:
       C:Program Files (x86)Microsoft SDKsWindowsv10.0AinNETFX 4.6.1 Tools
      

      使用如下命令,创建密钥文件:

       SN -k Answer.snk
      

      命令执行完毕后会在当前目录生成Answer.snk文件。

      注:必须以管理员身份打开命令行程序cmd.exe,否则无法创建密钥文件。

      如果要查看该密钥文件的实际公钥,执行以下两条命令:

       SN -p Answer.snk Answer.PublicKey sha256
       使用-p命令创建只含公钥的文件
      

       SN -tp Answer.PublicKey
       使用-tp命令显示公钥标记
      

    2. 使用密钥文件创建强命名程序集

      本节沿用上一篇中创建的CommonTypes.cs文件,将步骤1中生成的Answer.snk文件拷贝到D: est目录下,执行以下命令:

       C:WindowsMicrosoft.NETFramework64v4.0.30319csc.exe /t:library /keyfile:Answer.snk CommonTypes.cs
      

      C#编译器打开指定密钥文件(Answer.snk),用私钥对程序集进行签名,并将公钥嵌入清单中。生成强命名程序集时,程序集的FileDef清单元数据表列出构成程序集的所有文件,每将一个文件名添加到清单,都对文件内容进行哈希处理,哈希值和文件名一同被存入FileDef表中。使用ILDasm.exe工具查看程序集元数据,可以看到公钥已经被嵌入程序集清单中。


    ##全局程序集缓存

      创建了强命名程序集之后,我们就可以部署它了。文章的开头已经介绍,全局部署的程序集是指部署到一些公认位置的程序集,这个公认位置就是全局程序集缓存(Global Assembly Cache,GAC)。GAC位置如下:

    C:WindowsMicrosoft.NETassembly
    

    在GAC中安装或卸载强命名程序集最常用的工具是GACUtil.exe。

    GACUtil.exe位置:
    C:Program Files (x86)Microsoft SDKsWindowsv10.0AinNETFX 4.6.1 Tools
    

    将上一节中创建的CommonTypes.dll注册到GAC中,执行语句:

    gacutil.exe /i D:	estCommonTypes.dll
    

    提示注册成功后,路径C:WindowsMicrosoft.NETassemblyGAC_MSIL下生成CommonTypes文件夹。


    ##强命名程序集的引用

      任何程序集都包含对其他强命名程序集的引用,因为System.Object定义在MSCorLib.dll中,MSCorLib.dll就是强命名程序集。使用csc.exe的/reference编译器开关指定想引用的程序集文件时,若提供完整路径,csc.exe会加载指定文件,并根据它的元数据生成程序集;若指定不包含路径的文件名,csc.exe会在如下目录查找程序集:

    1. 工作目录
    2. csc.exe所在目录,目录中还包含CLR的各种DLL文件
    3. 使用/lib编译器开关指定的任何目录
    4. 使用LIB环境变量指定的任何目录

    虽然编译时会在这里查找程序集,但运行时不会在这里加载程序集。安装.NET Framework时,实际会安装两套程序集文件。一套在CLR目录,另一套在GAC的子目录。CLR目录下的文件便于生成程序集,而GAC中的文件便于运行时加载。

    强命名程序集防篡改


      用私钥对程序集进行签名,并将公钥嵌入程序集中,CLR就可以验证程序集是否被修改或破坏。程序集安装到GAC时,系统对包含清单的那个文件的内容进行哈希处理,将哈希值与PE文件中嵌入的RSA数字签名进行比较,值完全相同则表明文件内容未被篡改。此外,系统还会对程序集的其他内容进行哈希处理,并与清单文件的FileDef表进行比较。

    延迟签名


      只有少数人才能访问私钥,而开发和测试的过程中,需要经常对程序集进行修改,.NET Framework提供了延迟签名技术。延迟签名允许只使用公钥生成程序集,暂不用私钥,等到打包和部署程序集时再进行签名。下面总结了使用延迟签名技术开发程序集的步骤:

    1. 新建DelaySignSample.cs文件

       public class DelaySignSample
       {
           static void Main()
           {
               System.Console.WriteLine("Hello");
               System.Console.ReadLine(); 
           }
       }
      
    2. 使用公钥文件编译程序集

       csc /t:library /keyfile:Answer.PublicKey /delaysign DelaySignSample.cs
      

    3. 指定-Vr命令行开关,使CLR暂时信任程序集内容,不进行哈希建检验(这使得程序集能顺利安装到GAC,否则注册时会报错)

       SN.exe -Vr DelaySignSample.dll
      

    4. 项目开发完成后,使用私钥进行签名

       SN -R DelaySignSample.dll Answer.snk
      

    5. 重新启用对该程序集的验证

       SN -Vu DelaySignSample.dll
      


    ##运行时解析类型引用

      运行应用程序时,CLR会加载并初始化自身,读取程序集的CLR头,查找标识了应用程序入口方法(Main)的MethodDefToken,检索MethodDef源数据表找到IL代码在文件中的偏移量,将IL代码JIT编译成本机代码,最后执行本机代码。

    具体的执行过程在《CLR的执行模型》中已经详细介绍。

      下图展示了CLR加载程序集并扫描其元数据来定位类型的过程:

  • 相关阅读:
    常用的算法
    2017前端面试题
    深入了解php opcode缓存原理
    0=='aa'的结果是true
    关于PHP浮点数之 intval((0.1+0.7)*10) 为什么是7
    linux grep命令
    linux awk命令详解
    PHP socket模拟POST请求
    shell编程之sed
    Shell脚本常用判断
  • 原文地址:https://www.cnblogs.com/Answer-Geng/p/7308548.html
Copyright © 2020-2023  润新知