zoukankan      html  css  js  c++  java
  • .Net 强名浅析

    Assembly强名浅析

    首先需要明白几个信息:

    1. 什么是Assembly Qualified Name?

    Assembly Qualified Name 不等同于Assembly的文件名,也同时包含版本,公钥信息。例如:

    Test.Class1,Test,Version=1.3.0.0,Culture=neutral,PublicKeyToken=1234567890abcdef

    我们可以从Type.AsssemblyQualifiedName属性中取得

                Test.Class1 class1 = new Test.Class1();

                Type type = class1.GetType();

                Console.WriteLine(type.AssemblyQualifiedName);

    2. PublishKey和PublishkeyToken是什么关系?

    PublishKey是能标识一个开发者的个人信息,它是由128byte的数据加上32byte的头信息组成。它是用来标示一个Assembly的开发者。如果每次去Reference或者Load一个Assembly都需要输入这160字节的字符,未免太繁琐,于是我们可以用SHA 哈希算法生成(我们不需要自己做,.Net SDK提供了这样的工具,Sn.exe)一个只有8个字节的PublicKeyToken,每次用这个PublickKeyToken就可以让.Net Compiler或者Loader找到相应的Assembly了。

    因此在Assembly 中标识了PublicKeyToken信息就等于告诉编译器“导入XXX创建的dll”。

    3. Assembly强名的作用?

    Assembly强名的作用就是防止你的Assembly被别人冒充。

    现在假设一个LoadTest工程引入了一个未强名(publicKeyToken = null)的test.dll,这个dll的读入地址为c:\test.dll。那么,如果有hacker进入,将其中的test.dll替换成同名的dll,但是把其中函数的功能替换掉。那么LoadTest工程无法发现这个替换,因此编译运行仍然成功。

    为了杜绝这个情况,Assembly强名机制就产生了。

    如何为Assembly强名?

    下面是step by step的说明:

    1. 产生实验性的assembly,test.dll

    namespace test
    {
    public class Class1
    {
    public string A()
    {
    return "This is Test App";
    }
    }
    }

    2. 产生控制台工程LoadTest

    代码
    static void Main(string[] args)
    {
    Test.Class1 class1
    = new Test.Class1();
    Type type
    = class1.GetType();
    Console.WriteLine(type.AssemblyQualifiedName);
    Console.WriteLine(class1.A());
    }

    3.运行发现PublishKeyToken=null

    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")]到Test程序的AssemblyInfo.cs

    [assembly: AssemblyTitle("Test")]

    [assembly: AssemblyCulture("")]

    [assembly: AssemblyKeyFile(@"C:\Test\Debug\test.snk")]

    6.重新build Test工程,产生的dll替换LoadTest引用的test.dll

    7.运行LoadTest,发现PublishKeyToken有值了。

    PS:

    工程文件(.csproj)里面对每个Reference有说明,如:

    <Reference Include="Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=70c462b39226554f, processorArchitecture=MSIL">

          <HintPath>..\Test\bin\Debug\Test.dll</HintPath>

          <SpecificVersion>False</SpecificVersion>

    </Reference>

    所以当我们编译时候产生Token错误的时候,如果我们知道要引入正确dll的PublishKeyToken的时候,可以选择手动调整.csproj文件(笔者在工作中遇到过类似问题,产生的原因是由于引入dll的版本升级导致不匹配的问题)

    作者:Nick Ye(yjf512)
    出处:(http://www.cnblogs.com/yjf512/
    版权声明:本文的版权归作者与博客园共有。转载时须注明本文的详细链接,否则作者将保留追究其法律责任。

    参考文档:

    http://www.cnblogs.com/060218/archive/2009/11/19/1605951.html

    http://www.cnblogs.com/itech/archive/2009/09/11/1564921.html

    http://blog.csdn.net/Donjuan/archive/2009/02/02/3859136.aspx

    实时了解作者更多技术文章,技术心得,请关注微信公众号“轩脉刃的刀光剑影”

    本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

  • 相关阅读:
    0918作业-----所有数值未做合法性检测
    尝试安装和配置JDK,并给出安装、配置JDK的步骤
    java为什么可以跨平台执行
    字符集
    java 入门及简介
    时间轴特效
    javascript简介
    javascript while循环
    Javascript for循环
    函数豹子问题
  • 原文地址:https://www.cnblogs.com/yjf512/p/1839673.html
Copyright © 2011-2022 走看看