C#程序集使用强名字(Strong Name)签名/强名称签名
强名称签名的方法:
强签名:
1. 可以将强签名的dll注册到GAC,不同的应用程序可以共享同一dll。
2. 强签名的库,或者应用程序只能引用强签名的dll,不能引用未强签名的dll,但是未强签名的dll可以引用强签名的dll。
3. 强签名无法保护源代码,强签名的dll是可以被反编译的。
4. 强签名的dll可以防止第三方恶意篡改。
强签名的方法:
1. 有源代码:
1.1 使用vs tool command:snk –k mykey.snk 生成签名公钥。
1.2 将公钥加入项目中,并设置项目属性,设置签名公钥
1.3 重新生成项目。
2. 没有源代码。
2.1 创建强签名键:
sn.exe -k key.snk
2.2 反汇编dll为il
ILDASM.exe SomeLibrary.dll /OUTPUT=SomeLibrary.il
该指令会反汇编该dll并生成SomeLibrary.il,如果该dll含有嵌入的resource,
则会有SomeLibrary.res文件产生,并有相应的嵌入资源文件产生。
2.3 重新汇编为dll
ILASM.exe SomeLibrary.il /DLL /OUTPUT=SomeLibrary.dll /KEY=key.snk
如果有嵌入的资源文件,则需要加上 /RESOURCE=SomeLibrary.res
强签名的dll与未签名的在反编译后的区别:
未签名的:
强签名的:
更多详细信息参考 StringNaming
http://windowsdevcenter.com/pub/a/dotnet/2003/04/28/strongnaming.html
2. 用Sn.exe 生成一个Public/Private Key Pair 文件:Sn -k test.snk. 如果不指定大小,它的大小就是596 bytes(128 publicKey,32 publicKey Header, 436 PrivateKey)。
3. 添加 [assembly: AssemblyKeyFile(@"test.snk")] 到程序的AssemblyInfo.cs中,也可以在Build Option中指定(/keyfile:test.snk ). 再重新生成test.dll. 在VisualStudio中还可以用工程属性指定.
4. Sn -v test.dll 查一下test.dll是不是已经是一个strongname的程序了,输出:test.dll is valid。表示成功生成了一个具有PublicKey的程序 Sn -T test.dll 可以得到这个assembly的PublickKeyToken。
为什么使用强名称签名:
通过签发具有强名称的程序集,您可以确保名称的全局唯一性。强名称还特别满足以下要求:
强名称依赖于唯一的密钥对来确保名称的唯一性。任何人都不会生成与您生成的相同的程序集名称,因为用一个私钥生成的程序集的名称与用其他私钥生成的程序集的名称不相同。
强名称保护程序集的版本沿袭。强名称可以确保没有人能够生成您的程序集的后续版本。用户可以确信,他们所加载的程序集的版本出自创建该版本(应用程序是用该版本生成的)的同一个发行者。
强名称提供可靠的完整性检查。通过 .NET 框架安全检查后,即可确信程序集的内容在生成后未被更改过。但请注意,强名称中或强名称本身并不暗含某一级别的信任,例如由数字签名和支持证书提供的信任。
在引用具有强名称的程序集时,您应该能够从中受益,例如版本控制和命名保护。如果此具有强名称的程序集以后引用了具有简单名称的程序集(后者没有这些好 处),则您将失去使用具有强名称的程序集所带来的好处,并依旧会产生 DLL 冲突。因此,具有强名称的程序集只能引用其他具有强名称的程序集。
GAC
一、GAC的作用
全称是Global Assembly Cache作用是可以存放一些有很多程序都要用到的公共Assembly,例如System.Data、System.Windows.Forms等等。这样,很多程序就可以从GAC里面取得Assembly,而不需要再把所有要用到的Assembly都拷贝到应用程序的执行目录下面。举例而言,如果没有GAC,那么势必每个WinForm程序的目录下就都要从C:\WINDOWS\Microsoft.NET\Framework\vX下面拷贝一份System.Windows.Forms.dll,这样显然不如都从GAC里面取用方便,也有利于Assembly的升级和版本控制。
二、强命名程序集
因为不同的公司可能会开发出有相同名字的程序集来,如果这些程序集都被复制到同一 个相同的目录下,最后一个安装的程序集将会代替前面的程序集。这就是著名的Windows “DLL Hell”出现的原因。
很明显,简单的用文件名来区分程序集是不够的,CLR需要支持某种机制来唯一的标识一个程序集。这就是所谓的强命名程序集。
一个强命名程序集包含四个唯一标志程序集的特性:文件名(没有扩展名),版本号,语言文化信息(如果有的话),公有秘钥。
这些信息存储在程序集的清单(manifest)中。清单包含了程序集的元数据,并嵌入在程序集的某个文件中。
下面的字符串标识了四个不同的程序集文件:
“MyType, Version=1.0.1.0,
Culture=neutral, PublicKeyToken=bf5779af662fc055”
“MyType, Version=1.0.1.0,
Culture=en-us, PublicKeyToken=bf5779af662fc055”
“MyType, Version=1.0.2.0,
Culture=neturl, PublicKeyToken=bf5779af662fc055”
“MyType, Version=1.0.2.0,
Culture=neutral, PublicKeyToken=dbe4120289f9fd8a”
如果一个公司想唯一的标识它的程序集,那么它必须首先获取一个公钥/私钥对,然后将共有秘钥和程序集相关联。不存在两个两个公司有同样的公钥/私钥对的情况,正是这种区分使得我们可以创建有着相同名称,版本和语言文化信息的程序集,而不引起任何冲突。
与强命名程序集对应的就是所谓的弱命名程序集。(其实就是普通的没有被强命名的程序集)。两种程序集在结构上是相同的。都使用相同的PE文件格式,PE表头,CLR表头,元数据,以及清单(manifest)。二者之间真正的区别在于:强命名程序集有一个发布者的公钥/私钥对签名,其中的公钥/私钥对唯一的标识了程序集的发布者。利用公钥/私钥对,我们可以对程序集进行唯一性识别、实施安全策略和版本控制策略,这种唯一标识程序集的能力使得应用程序在试图绑定一个强命名程序集时,CLR能够实施某些“已确知安全”的策略(比如只信任某个公司的程序集)。
三、如何创建强命名程序集, 如何查看强命名程序集的PublicKeyToken
如何创建强命名程序集
===================
1. 在Visual Studio中的class library工程上点右键, 选择properties.
2. 选择左边的Signing选项卡.
3. 勾选Sign the assembly复选框. 在下拉列表中选择<New...>.
4. 在弹出的对话框中给snk文件起一个名字. 按OK.
5. 程序集强命名完成.
如何查看强命名程序集的public key token
=========================
有时候你需要在web.config文件中或者其他地方引用自己写的强命名程序集, 你需要写入像下面这样的fully qualified name:
MyNamespace.MyAssembly, version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
前面三个部分比较容易获得, 因为是你自己写的, 你当然知道assembly的名字, 版本, 还有culture信息. 比较麻烦的部分是如何获得自己签名的程序集的public key token. 一种平常的方法是使用Reflector来打开自己的程序集, 然后获得token(实际上, Reflector会给你如同上面例子那样的完整信息). 但是这有的时候还是显得有点未免杀鸡用牛刀了. 如果你已经打开了Visual Studio, 那么仅仅是在VS的菜单里点一个菜单项就能获得答案不是更好么? 下面就是步骤.
1. 在Visual Studio中, 打开Tools菜单, 然后点击External Tools这个菜单项.
2. 在弹出的External Tools对话框中, 点击Add按钮.
3. 按照下图进行配置. sn.exe这个工具在不同版本的VS下处于不同的文件夹中. 最简单的找到它的方式是在VS Command Prompt中输入"where sn.exe". 在参数框里写入"-T $(TargetPath)". 然后勾选"Use Output Window". 这样的话, 结果就会在VS的output window. 然后点击OK,
4. 结果如图.
5. 在输出窗口可以看到结果. 这在你的solution里有多个project的时候也是可以正常工作的. 只需要点击一下Solution Explorer中的Project, 然后点击我们的菜单项就可以了.
四、如何将自己的dll注册到GAC中
在开发和测试中,最常用的工具就是GACUtil.exe。 在GAC中注册程序集跟COM注册差不多,但相对更容易:
1.把程序集添加到GAC中: GACUtil /i sample.dll (参数/i是安装的意思)
2.把程序集移出GAC GACUtil /u sample.dll (参数/u就移除的意思)
注意:不能将一个弱命名程序集安装到GAC中。
如果你试图把弱命名程序集加入到GAC中,会收到错误信息:”
Failure adding assembly to the cache: Attempt to install an assembly without a strong name”
d)强命名程序集的私有部署
例子:
C:\Program Files\Microsoft Visual Studio 8\VC>gacutil -i F:\myweb\BalloonShop\Cl
assLibrary1\bin\Debug\ClassLibrary1.dll
在C:\WINDOWS\assembly将会看到ClassLibrary1,注册成功
五、查看GAC文件内容以及将DLL复制出来
在项目中我们常常会引入第三方的dll,一般情况下我们都可以将所需的dll文件复制到硬盘上的一个地方,然后在项目中添加引用,这个操作很简单!但有时候我们会遇到这样的情况,就是所要引用的dll在目标机器的GAC里,这时我们就不能手动将它拷贝出来了。
其实Windows的GAC是有对应的目录的,一般来说为c:\Windows\assembly\,这个目录有一些特殊,它里面存放的是本机已安装和注册的类库dll,并且不允许用户直接对其中的元素进行相关操作(如复制、剪切、粘贴、修改名称等),不过你可以直接将另一位置的dll文件直接拖放到这个目录下进行dll的安装,但是我们不能直接将已经安装进去的dll再拷贝出来。这里我将介绍一种方法来完成这个操作。
首先我们切换到Windows的命令行方式,即开始-运行-cmd-回车,然后转到GAC所在的目录,利用dir命令查看一下其中的内容,如下图。
似乎可以明白GAC中的目录结构了,基本上我们可以根据GAC目录中的Processor Architecture列来区分dir的类型,例如我们要找的System.Web.Extensions属于MSIL,在CMD方式下它应该就对应GAC_MSIL,然后切换到这个目录下并dir。
看到我们要找的System.Web.Extensions程序集了,它也是一个dir,继续切进去并dir。
这时只有一个目录了,继续切进去,然后dir就可以看到我们最终想要的dll文件了,然后通过copy命令将它复制出来就OK了!
小技巧:在CMD方式下使用命令时,如果要输入的文件名或目录名太长,可以先敲部分字符,然后通过Tab键自动补全,Windows的command工具会自动为你找到相匹配的内容!
六、例子
如上图所示,新建了2个类库文件:ClassLibrary1、ClassLibrary2
1、使用上面的第三点创建了强类型程序集ClassLibrary1,并且注册到GAC中(可以使用上面第三点的方法,也可以使用反编译器进行反编译,可以查看到PublicKeyToken值。ClassLibrary2为null,ClassLibrary1为568e03e6162a7a2e)。
2、在DataAccess中引用ClassLibrary1、ClassLibrary2,编译DataAccess。
3、进入DataAccess工程的bin\debug文件夹下,只有ClassLibrary2.dll与DataAccess.dll(没有ClassLibrary1.dll)
由此可知:程序是从GAC中直接取得ClassLibrary1.dll的而不是从ClassLibrary1工程中将ClassLibrary1.dll拷贝到自身的debug中进行引用。
C#程序集使用强名字(Strong Name)签名/强名称签名的更多相关文章
- .net程序集强名称签名实践
引用: http://www.cnblogs.com/cpcpc/archive/2011/01/17/2123086.html 强名称是由程序集的标识加上公钥和数字签名组成的.其中,程序集的标识包 ...
- 强(strong)、软(soft)、弱(weak)、虚(phantom)引用
https://github.com/Androooid/treasure/blob/master/source/lightsky/posts/mat_usage.md 1.1 GC Root JAV ...
- .NET Core 使用RSA算法 加密/解密/签名/验证签名
前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...
- md5只是用来签名,签名的作用是保证数据完整不会被破坏而已。签名和加密是两回事
md5只是用来签名,签名的作用是保证数据完整不会被破坏而已,多一个sign标签,sign的值就是md5生成的字符串.签名和加密是两回事
- 未能加载文件或程序集“Enyim.Caching”或它的某一个依赖项。未能验证强名称签名
from:http://www.mzwu.com/article.asp?id=3741 itHub下载Enyim项目,编译后引用程序运行出错: 引用内容 未能加载文件或程序集“Enyim.Cachi ...
- 强引用strong和弱引用weak的定义
1.强引用表示从属关系,引用对象拥有被引用的对象.弱引用则暗示引用对象不拥有被引用的对象.一个对象的寿命是由它被强引用多少次来决定的.只要对象还存在强引用,就不会释放该对象. 注意:但是对象之间的引用 ...
- java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)
之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...
- Android 签名(8)签名前用Zipalign简单优化
1 为什么要优化 Android SDK中包含一个“zipalign”的工具,它能够对打包的应用程序进行优化.在你的应用程序上运行zipalign,使得在运行时Android与应用程序间的交互更加有效 ...
- Android 签名(7)签名常见问题,debug签名和release签名的区别等
一般在安装时提示出错:INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES 1) 两个应用,名字相同,签名不同 2) 升级时前一版本签名,后一版本没签名 3) ...
随机推荐
- linux字符过滤
1 案例一:取eth0的IP地址 方法一:通过cut方法过滤 [root@baiguin ~]# ifconfig eth0|grep "inet addr:"|cut -d & ...
- 工作中的问题解决 -- (win2003 asp.net) Session和带页面回传的方法无法正常使用解决方案
公司BP&IT项目组.从上上个月成立开始开发BP&IT软件.这个月开始测试我悲剧的发现他尽然不支持我电脑上的IE11.半个多月还没解决 我们先来分析下原因首页 登陆页面正常浏览 htt ...
- == 和 equals()的区别
package com.liaojianya.chapter1; /** * This program demonstrates the difference between == and equal ...
- IOS 学习笔记 20150314
Objective--C 类与对象 1 关键字 @interace 类定义 @end 类结束 @implementation 类实现 : 继承 @public 公用 @private 私有 @prot ...
- Javascript数组的indexOf()、lastIndexOf()方法
在javascript数组中提供了两个方法来对数组进行查找,这两个方法分别为indexOf(),lastIndexOf(). 这两个方法都有两个参数,第一个参数为需要查找的项,第二个参数则是查找的起始 ...
- webapp中的日期选择
你是否在开发webapp时,选择用哪种第三方日期选择控件绞尽脑汁? 其实不用那么麻烦,现在移动端都是WebKit内核,支持HTML5,其实只要弱弱的将input中将type="date&qu ...
- php Static静态关键字
静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用.静态属性不允许对象使用->操作符调用. class Car { private static $speed = ...
- 小笔记(二):php数组
一.对于一二维数组重新组合为另一个二维数组,根据键值名称对一个二维数组进行重新组合例: /*$paramArray=array( * 'a'=>array('0'=>'1','1'=> ...
- Xcode报错 - 1
1. xcode在真机调试的时候出现"The identity used to sign the executable is no longer valid" 解析: 是由于.pr ...
- sublime 编译程序出错控制台打印PATH的解决办法
找到sublime的安装目录 搜索 exec.py 打开找到这几句话193行左右或者搜索关键词path if "PATH" in merged_env: self.debug_te ...