1. 两种程序集,两种部署

备注:
公认位置:由多个应用程序访问的程序集必须放到公认的目录,而且CLR在检测到对该程序集的引用时,必须知道检查该目录。这个公认位置就是全局程序集缓存(Global Assembly Cache GAC)。GAC的具体位置是一种实现细节,不同版本会有所变化(%SystemRoot%\Microsoft.NET\Assembly)
2.为程序集分配强名称
2.1 第一步:用.NET Framework SDK和VS随带的Strong Name使用程序(SN.exe)获取密钥
MyKey.snk文件中包含二进制形式的公钥和私钥。私钥内容是不允许查看的,但可以看公钥的内容。这需要执行两次SN.exe。
1)第一次:用-p开关创建只含公钥的文件
2)第二次:用-tp开关执行,传递只含公钥的文件。由于公钥太大,难以使用,因而有了公钥标记(64位哈希值)
第二步:创建强名称程序集---编译程序时使用/keyfile:<file>编译器开关
C#编译器看到这个开关会打开指定文件,用私钥对程序集进行签名,并将公钥嵌入清单。注意只能对含清单的程序集进行签名;程序集其他文件不能被显示签名。
此时,我们可以显示其中包含的公钥标记,看看是否和上面相同:
由此可见,公钥的内容确实嵌入到了程序集当中。
注意:也可通过VS工具进行签名。
3. 全局程序集缓存
由多个应用程序访问的程序集必须放到公认的目录,而且CLR在检测到对该程序集的引用时,必须知道检查该目录。这个公认位置就是全局程序集缓存(GAC)。GAC的具体位置一般在以下目录:
1)开发和测试时在GAC中安装强命名程序集最常用的工具是GACUtil.exe。直接运行,会自动显示用法:
2)接下来将程序集添加到GAC
3)需要管理员权限
4. 强命名程序集能防篡改
用私钥对程序集进行签名,并将公钥和签名嵌入到程序集中。在程序集安装到GAC时,系统会对包含清单的文件的内容进行哈希处理,将得到的哈希值与PE文件中嵌入的RSA数字签名进行比较,值不一致,则表明程序集被修改。此外,系统还对程序集的其他文件进行哈希处理,并将哈希值与清单文件的FileDef表中存储的哈希值进行比较。任何一个哈希值不一致,表明程序集至少有一个文件被篡改,程序集无法安装到GAC中。
应用程序需要绑定到程序集时,CLR根据被引用程序集的属性在GAC中找到对应的程序集,以此确保运行时加载的程序集和最初编译时生成的程序集来自同一个发布者,因为进行引用的程序集的AssemblyRef表中的公钥标记与被引用程序集的AseemblyRef表中的公钥匹配。如果被引用的程序集不在GAC中,CLR会查找应用程序的基目录,然后查找应用程序配置文件中标注的任何私有路径。然后,如果应用程序由MSI安装,CLR要求MSI定位程序集。如果在任何时候都找不到程序集,则会报错。
5. 延迟签名
1)为什么要延迟签名?
如果要生成一个强命名的程序集,那么每次生成都需要进行签名,在开发的时候就会频繁的访问私钥文件,而私钥文件一般都是非常保密的,想要频繁使用可能有些费事。所以就有了延迟签名的机制。延迟签名的意思就是在开发阶段,只把公钥提供给开发人员,只有公钥对程序集进行签名,在最后打包发布的时候,才使用私钥来进行签名。
打包一个程序集前,只要你希望对它执行其他任何操作,延迟签名都非常有用。例如,可能想要对自己的程序集运行一个混淆器(obfuscator)程序。程序集在完全签名后,便不能再对它运行混淆器,否则哈希值就不正确了。所以,要想混淆一个程序集文件,或者进行其他形式的"生成后"(post-build)操作,就应该使用延迟签名,执行所有必要的"生成后"操作,再用-R或-Rc开关运行SN.exe,最终完成对程序集的签名。
2)如何实现延迟签名?
第一种方式通过VS工具包:
第二种通过命令行:
开发期间,获取只含公司公钥的文件,使用/keyfile和/delaysign编译器开关编译程序集根据时间可知已被重新编译
生成程序集后,使CLR暂时信任程序集的内容,不对它进行哈希处理,也不对哈希值进行比较,同时也可使程序集顺利安装到GAC。
准备好打包和部署程序集时,获取私钥并执行以下命令
重新启用对这个程序集的验证