zoukankan      html  css  js  c++  java
  • 为程序集赋予强名称并使用

          SN是.NET中提供生成密钥的工具,在对程序集进行强签名的时候,需要用到一个公钥对,用这个工具,可以生成一个密钥文件,同时可以查看文件里面的公钥,并且可以使用这个工具来对程序集进行强签名。延迟签名的时候也需要使用这个工具。这个工具一般是在C:Program FilesMicrosoft SDKsWindowsv7.0Ain 或 C:Program Files (x86)Microsoft SDKsWindowsv7.0ABin 这个路径下。启动这个工具,界面如下:

    为程序集赋予强名称的步骤如下
    第一步:生成公钥/私钥对(生成martinsnk.snk文件)
    sn -k D:martinsnk.snk
    说明:1)每次调用sn时,创建的私钥/密钥对文件都不相同,不仅自己的计算机每次生成的不同,其他所有计算机生成的也不相同。
            2)关于这个文件的命名,如果是个人,可以以自己的名字命名;如果是团队、组织或公司,可以以组织名称来命名。如TraceFact公司可以为TraceFact.snk。
            3)在大多数情况下,个人和组织只需要一个snk文件就可以了,以后创建强名称的时候,都使用这个snk文件。由于会使用snk文件的私钥对强名称程序集进行签名,因此这个文件必须严密保护。

    第二步:生成公钥(martinsnk.pk),使用sn.exe执行命令:
    sn -p D:martinsnk.snk D:martinsnk.pk

    第三部:可以使用sn来查看公钥具体值和公钥标记,执行命令:
    sn -tp D:martinsnk.pk
    说明:公钥的字节数很长,有128字节,操作起来很不方便。因此,对公钥进行了散列运算,获得了一个它的8字节的哈希值,也就是公钥标记。对于开发者来说,只要关注公钥标记就可以了。

     

          现在,就可以唯一确定一个程序集了。此时,如果还是按照为程序集加特性标记的方式来写入PublicKeyToken,例如:[assembly:PublicKeyToken("c3084eebf658444c")]

    那么和使用GUID是完全一样的,没有起到防仿冒的作用。由于公钥和公钥标记是公开的,其他人也可以为自己的程序集设置和你相同的PublicKeyToken。显然,使用程序集特性标记来写入PublicKeyToken并不合适。正确的使用方式,这里举一个例子,比如,当使用Visual Studio时,可以先进入项目属性,然后进入“签名”选项卡,勾选“为程序集签名”选项,点击“选择强名称密钥文件”下拉框,然后选中martinsnk.snk密钥文件,如图:

     

    仅就程序集唯一性来说,使用公钥标记就够了。但使用公钥/私钥对的作用不仅限于此,还可以防篡改和数字签名(这里就不多说了)。

    说道强名称程序集,这里就谈谈全局程序集缓存(GAC,Global Assembly Cache)。

    为什么会用到程序集缓存呢?比如这种情况,当多个程序引用同一个程序集时,可以将它放在一个公共的共享文件夹,但是这个文件夹又不能像System32文件夹一样,以文件名来对程序集进行区分,否则就会出现后安装的程序集将之前安装的同名程序集覆盖的问题。在.NET中,这个特殊的文件夹叫做全局程序集缓存(GAC,Global Assembly Cache),它的位置是C:WindowsAssembly,进入这个文件夹是这样:

    GAC文件夹的底层结构与普通文件夹是不同的,因此不能直接将程序集复制进去,而要通过GAC实用工具来完成。这个实用工具的名称叫做GacUtil.exe,打开“Visual Studio命令提示”,可以通过下面的语句将程序集安装至GAC:

    gacutil -i D:martinsnk.dll

    在从GAC中卸载程序集时,可以使用下面的命令:

    gacutil -u martinsnk(还可以更加具体准确点:gacutil -u martinsnk,Version=1.1.0.0,Culture=neutral,PublicKeyToken=81e738080cc1bdc3)

    卸载程序集时需要注意:

    1)在卸载程序集时,不要输入.dll后缀,martinsnk.dll是文件名,不是程序集名。如果输入.dll后缀,会出现错误提示“找不到与以下内容匹配的程序集:martinsnk.dll”。
    2)程序集的全名称之间默认是存在空格的,需要删掉空格,否则会出现“未知选项Version=1.1.0.0”,因为命令行的选项是以空格为分隔的,会将Version误认为一个选项。
    3)如果输入命令gacutil-u martinsnk,取消后面的版本号、区域性、公钥标记,则会卸载所有名称为martinsnk的程序集。

    将程序集安装到GAC之后,就可以对它进行引用了。对于开发者来说,引用GAC程序集其实与引用非强名称程序集并无明显区别,但在引用GAC程序集时,并不会像引用非强名称程序集一样,复制一份程序集的副本到应用程序根目录下。现在,我们也仿照微软的做法来引用GAC程序集:

    1)创建一个文件夹D:SharedAssembly,这个文件夹下存放了所有我们自己的、安装到GAC中的程序集。将文件夹结构创建为:D:SharedAssembly程序集名版本号。

         对于本例来说,是     D:SharedAssemblymartinv1.1。然后将martin.dll复制进来。
    2)运行gacutil-i D:SharedAssemblymartinv1.1martin.dll,将程序集安装至GAC。
    3)打开之前创建的控制台项目ConsoleApp,然后引用D:SharedAssemblymartinv1.1下的martin。
    4)生成ConsoleApp,查看一下Debugin文件夹,会发现并没有martin.dll文件。这是引用GAC程序集与引用非强名称程序集的一个重要区别:不会复制一份martin.dll的副本到应用程序根目录。
    5)查看ConsoleApp项目中“引用”文件夹下martin的属性,路径为:D:Shared-Assemblymartinv1.1martin.dll。
    6)运行ConsoleApp,一切正常。作为试验,删掉D:SharedAssemblymartinv1.1文件夹下的martin.dll,再次运行ConsoleApp,依然没有问题,说明运行时加载的是GAC中的程序集。

     

     

    QQ交流群:338665589(本群创建于2017-5-10)

  • 相关阅读:
    verilog RTL编程实践之四
    TB平台搭建之二
    hdu3466 Proud Merchants
    poj2411 Mondriaan's Dream (用1*2的矩形铺)
    zoj3471 Most Powerful
    poj2923 Relocation
    hdu3001 Travelling
    poj3311 Hie with the Pie
    poj1185 炮兵阵地
    poj3254 Corn Fields
  • 原文地址:https://www.cnblogs.com/msAspnet/p/6836904.html
Copyright © 2011-2022 走看看