.NET中的PublicKeyToken以及强命名问题
2020-12-13 01:49
标签:style blog class code tar color
DLL Hell 是指当多个应用程序试图共享一个公用组件(如某个动态连接库(DLL)或某个组件对象模型(COM)类)时所引发的一系列问题。最典型的情况是,某个应用程序将要安装一个新版本的共享组件,而该组件与机器上的现有版本不向后兼容。虽然刚安装的应用程序运行正常,但原来依赖前一版本共享组件的应用程序也许已无法再工作。 然后GAC的出现,解决了这个问题。GAC中对于可以同时存在同一个DLL的多个不同的版本。如果多个程序都用到了这个DLL,那么这个程序就可以到GAC中去找相应版本的DLL.但是在GAC中,比如说同一个Data.dll,即使有多个版本的文件,但是其文件名都应该全是Data.dll,而且在不同的目录总,其version信息不是在文件名中体现出现了,而是在DLL的头信息中存储的。每个程序都会有一个程序集清单,这个清单存在和程序同名的.manifest文件中,里面列出其所需要的所有依赖,这儿所列出的依赖可不是简单地靠文件明来区分的,而是根据一种叫做“强文件名”的东西区分的。
其实PublicKeyToken就是Public Key的简单形式,我们就可以把PublicKeyToken当成PublicKey.这里说明一下PublicKeyToken的存在。PublicKeyToken的作用就是确定要加载的DLL一定要是最初的那个DLL,其实,这一方面也起到了安全方面的防范问题。比如说,有的程序,有人写了一个同名的DLL覆盖了你原来的DLL,程序如果不加分辨就使用这个DLL,可能就有安全问题了。那么PublicKeyToken是这么样来确保这个唯一性的呢?
这里涉及到了加密算法。最初DLL的开发者在开发这个DLL的时候,会加密这个DLL,使用的加密方法就是公钥私钥的方法。公钥与私钥是同时存在并且唯一对应的。对于同一段内容,用私钥加密之后,只有用公钥才能解密。如果用其他的私钥加密的东西,用这个公钥是解不开任何东西的。DLL开发者有自己的私钥,而这个私钥别人是不知道的,是保密的,在DLL开发的时候用私钥加密,并且把公钥信息写入到程序中。当这个程序开发完成后,在一台计算机上运行的时候,系统会从程序的程序清单中去找用到了哪个DLL,并且去查看这个DLL的版本,而且要用PublicKeyToken来确保这个DLL的原始性。那么是通过一个怎么样的过程来确保这个DLL的原始性呢?比如说,有一个人在你的电脑上,在你安装好这个程序后,到你程序的安装目录下,用一个同名的,具有同样的命名空间和类的DLL替换掉了你原来的DLL,系统是怎么能够发现的呢?程序在运行的时候,会从程序的程序清单中取看用到了哪个dll,这个dll的公钥是多少。(我认为这个程序清单是轻易不能被篡改的,如果这个都能篡改了,那么程序就无安全性可言了。起码我是这样认为的。)然后去GAC中或者程序的目录下寻找这个DLL。在这个DLL的头文件中有一些信息,是DLL的内容和加密后的字符串。程序会用公钥去解密这个字符串,如果解密出的内容和DLL中记录的内容一致,那么就证明这个DLL是原始的,没有被篡改过的。 有时候会在Web.config文件中Runtime标签下看到一些
.NET中的PublicKeyToken以及强命名问题,搜素材,soscw.com .NET中的PublicKeyToken以及强命名问题 标签:style blog class code tar color 原文地址:http://blog.csdn.net/sundacheng1989/article/details/25101309
我们发现原来这是一个XML格式的文件,其中
下面我们考虑几种可能被篡改的情况
有人仅仅修改了DLL的内容,并没有修改加密后的值,此时很容易被程序发现出来,因为解密后的值和DLL内容不一致,程序会提示异常。
有人不仅修改了DLL的内容,还想修改加密后的值,但是要知道,此时的用户是没有原来的开发者的私钥的,如果他随便用一个私钥加密,那么在程序解密的是,用那个公钥是解密不出来任何东西的,因为公钥私钥是对应的。此时,程序会提示异常。这篇文章比较细致的解释了公钥私钥对于DLL加密的过程。
总结:PublicKeyToken或者PublicKey不仅仅是用于安全方面,也是用于区别同一个DLL的不同版本方面。其实在一般的开发中我们用到的不多,最起码从我自己浅薄的经验来讲,接触的不多,基本上是透明的。