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
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的版本升级导致不匹配的问题)
本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2010/09/30/1839673.html,如需转载请自行联系原作者