.NET中的PublicKeyToken以及强命名问题
在.NET的GAC出现之前,以前有DLL Hell的问题。这是由于当时对于共享的DLL的处理方式。是通过採用注冊表的方式实现的。当我们安装一个程序A的时候,这个程序包括一个共享的DLL,那么这个DLL就会就会写入到注冊表中,可是注意这里并没有写入版本号信息,仅仅是告诉你在哪个地方有一个叫做XX的DLL能够使用。
当安装另外的一个程序B的时候。也包括这个共享的DLL,可是是一个更加新一些的版本号,系统会发现这个DLL已经注冊存在了。就会用这个DLL去覆盖原来的DLL,可是由于注冊表中前后没有不论什么版本号的标示,所以系统还是觉得这就是一个DLL.
可是如今已经更新了DLL。A程序可能会出现使用这个DLL的时候不兼容的现象。可是此时假设你重装A程序,再把共享DLL换回去。那么B程序又可能出现不兼容的现象。这就是DLL HELL问题。引发这个问题的解决办法,还是同一个DLL不能多个版本号同一时候存在的问题。
DLL Hell 是指当多个应用程序试图共享一个公用组件(如某个动态连接库(DLL)或某个组件对象模型(COM)类)时所引发的一系列问题。
最典型的情况是,某个应用程序将要安装一个新版本号的共享组件,而该组件与机器上的现有版本号不向后兼容。尽管刚安装的应用程序执行正常。但原来依赖前一版本号共享组件的应用程序或许已无法再工作。
然后GAC的出现,攻克了这个问题。
GAC中对于能够同一时候存在同一个DLL的多个不同的版本号。假设多个程序都用到了这个DLL。那么这个程序就能够到GAC中去找对应版本号的DLL.可是在GAC中。比方说同一个Data.dll,即使有多个版本号的文件。可是其文件名称都应该全是Data.dll。并且在不同的文件夹总,其version信息不是在文件名称中体现出现了,而是在DLL的头信息中存储的。每一个程序都会有一个程序集清单。这个清单存在和程序同名的.manifest文件里。里面列出其所须要的全部依赖,这儿所列出的依赖可不是简单地靠文件明来区分的,而是依据一种叫做“强文件名称”的东西区分的。
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture=' x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>
我们发现原来这是一个XML格式的文件。当中<dependency>这一部分指明了其依赖于一个名字叫做Microsoft.VC80.CRT的库。可是我们发现,<assemblyIdentity>属性里面还有其他的东东。各自是 type系统类型,version版本号号,processorArchitecture平台环境,publicKeyToken公匙(一般用来标示一个公司)。把他们加在一起便成了“强文件名称”了,有了这样的“强文件名称”。我们就能够依据其区分不同的版本号、不同的平台。总之。有了这样的强文件名称,系统中能够有多个不同版本号的同样的库共存而不会发生冲突。
事实上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是原始的,没有被篡改过的。
以下我们考虑几种可能被篡改的情况
有人只改动了DLL的内容,并没有改动加密后的值。此时非常easy被程序发现出来。由于解密后的值和DLL内容不一致,程序会提示异常。
有人不仅改动了DLL的内容,还想改动加密后的值。可是要知道,此时的用户是没有原来的开发人员的私钥的,假设他随便用一个私钥加密,那么在程序解密的是,用那个公钥是解密不出来不论什么东西的,由于公钥私钥是相应的。此时,程序会提示异常。这篇文章比較仔细的解释了公钥私钥对于DLL加密的过程。
有时候会在Web.config文件里Runtime标签下看到一些<runtime>bindingRedirect的内容,这里涉及到了PublicKey。
这里的作用是把不同版本号的文件映射到某一个特定的版本号,即程序清单中记载的某个dll是2.0的版本号,但是程序在执行的时候在GAC中仅仅找到1.0的版本号,那么告诉程序此时不提示异常。仅仅要把这个1.0版本号当成2.0版本号就能够了。
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
总结:PublicKeyToken或者PublicKey不不过用于安全方面。也是用于差别同一个DLL的不同版本号方面。
事实上在一般的开发中我们用到的不多。最起码从我自己浅薄的经验来讲,接触的不多,基本上是透明的。
.NET中的PublicKeyToken以及强命名问题的更多相关文章
- .NET中查看一个强命名程序集(*****.dll)的PublicKeyToken的方法
使用命令行工具SDK Command Prompt,键入:SN -T C:\*****.dll (dll文件所在的路径) 就会显示出该dll具体的PublicKeyToken数值. 如果该程序集没有 ...
- DevExpress 重编译 替换强命名 修改源码
本文以DevExpress 11.1.8举例 必须满足几个条件 1. 必须有DXperience相应版本的全部源代码SourceCode.把全部源代码复制到X:\Program Files\DevEx ...
- CLR 关于强命名程序集 .
如何创建强命名程序集(Strong Name Assembly) 创建一个强命名程序集首先需要获得一个用强命名实用工具 (Strong Name Utility,即SN.exe,.NET ...
- C# 强命名程序集,防止dll被修改,混淆下发布
未能加载文件或程序集“Jonckers.Service.RedisCacheEngineExtend, Version=1.0.0.0, Culture=neutral, PublicKeyToken ...
- .NET程序集强命名删除与再签名技术 源代码剖析
如果你想去除一个程序集的强签名(strong name),目前为止可以有两个途径 1 反编译为IL代码,删除签名部分,再编译为程序集 2 应用Re-Sign程序,直接对一个程序集再签名 生成和读取 ...
- .net程序集强命名(签名)
要想得到强签名的dll有两种情况: 1.给项目添加强命名 在你的项目右键->属性->签名,勾选“为程序集签名”,新建 或 浏览已经新建过的.pfx文件,然后重新build项目,生成的dll ...
- membership DB生成 & dll 强命名 & 证书生成
UPD(Membership)数据库安装1.使用 Aspnet_regsql.exe 安装数据库 在 C:\WINDOWS\Microsoft.NET\Framework\\aspnet_regsql ...
- 记一次dll强命名冲突事件
一 问题的出现 现在要做一个net分布式平台,平台涉及多个服务之间调用问题,最基础的莫过于sso.由于我们的sso采用了wcf一套私有框架实现,另外一个webapi服务通过接口调用sso服务.由于s ...
- 只有ReflectionOnlyLoadFrom才可以拯救与GAC冲突的强命名程序集
先说结论,如果有两个拥有相同程序集名称的强命名程序集,一个在GAC里,一个不在.怎样动态加载那个不在GAC里的程序集?答案就是只有Assembly.ReflectionOnlyLoadFrom才可以加 ...
随机推荐
- 【C语言】控制台窗口图形界面编程(一)句柄和文本属性
目录 00. 目录 01. 句柄 02. GetStdHandle函数 03. CloseHandle函数 04. SetConsoleTextAttribute函数 05. 十进制颜色对照表 06. ...
- iis如何在dos中注册
iis如何在dos中注册 2009-09-23 08:13 提问者采纳 cd \cd c:\windows\microsoft.net\framework\v2.0.50727aspnet_r ...
- ORACLE中的游标Cursor总结
游标(Cursor):用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作. 游标可分为: 1. 静态游标:分为显式(explicit)游标和 ...
- 趣味ACM题——圣骑士的斩杀
题目来源于山东省第七届ACM大学生程序设计竞赛(Execution of Paladin) 题目描述 鱼人是炉石里的一支强大种族,在探险者协会里,圣骑士有了一张新牌,叫亡者归来,效果是召唤本轮游戏中7 ...
- css3新特性学习系列 -- border
css3新特性 border属性(border-radius.border-image.box-shadow)详解 1.border-radius 圆角 支持:IE9+ 用法: border-rad ...
- PHP:分页类(比较庞大不建议在项目中用)
文章来源:http://www.cnblogs.com/hello-tl/p/7685178.html <?php //地址 //page::$url=''; //每页的条数 默认10 //pa ...
- LeetCode(49)Group Anagrams
题目 Given an array of strings, group anagrams together. For example, given: ["eat", "t ...
- Windows学习总结(12)——Windows 10系统开始运行-cmd命令大全
gpedit.msc-----组策略 sndrec32-------录音机 Nslookup-------IP地址侦测器 explorer-------打开资源管理器 logoff---------注 ...
- C51 独立按键 个人笔记
独立按键类似于一个开关,按下时开关闭合 防抖 硬件防抖 软件防抖 通过延时,滤掉抖动的部分 电路图 普中科技的开发板,独立按键电路图如下 判断按键按下 因此判断是否按下开关的方法是看引脚是否为低电平( ...
- 关于Web服务接口测试的一些问题及答案
本篇主要是像想要了解并且学习接口测试的朋友,做一个入门的简单介绍 1.什么是接口 答:接口就是内部模块对模块,外部系统对其他服务提供的一种可调用或者连接的能力的标准,就好比usb接口,他是系统向外接提 ...