代码改变世界

.Net 强名浅析

2010-09-30 18:45 轩脉刃 阅读(...) 评论(...) 编辑 收藏

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