CLR:共享程序集和强命名程序集(上)

CLR:共享程序集和强命名程序集(上)
 

强命名程序集使用发布者的公钥/私钥对进行了签名,它唯一性地标识了程序集的发布者。它是为解决版本控制问题而建立的基础结构

程序集的两种部署方式:私有部署和全局部署

私有部署的程序集是指部署到应用程序基目录或者它的某个子目录中的一个程序集。

全局部署的程序集是指部署到一些已知位置的程序集:CLR在查找程序集时,会自动检查这些位置。

 为程序集指派强名称

如果多个应用程序准备访问一个程序集,程序集就必须放到一个已知的目录中。在检测到对程序集的一个引用时,CLR必须能够自动检查这个目录。但现在的问题是:两个公司可能生成具有相同文件名的程序集。所以,假如两个程序集都复制到同一个已知目录中,最后一个安装的就会胜出,造成正在使用旧程序集的所有应用程序都无法正常工作(这正是WindowsDLL hell现象的根源)。

显然,只是根据文件名来区分程序集是不够的。CLR提供了一种强命名的程序集机制来唯一性地标示程序集。它包括:

文件名(无扩展名)

版本号

语言文化

公钥

由于公钥是非常大的数字,所以使用这个公钥的64位的哈希值,称为“公钥标记”。

System.Reflection.AssemblyName是一个辅助类,利用它可以轻松地构建一个程序集名称,并获取程序集的各个部分。

 创建强命名程序集:

第一步:使用Strong Name 实用程序SN.exe(在SDK中)来获取一个公钥/密钥对。所有命令开关都区分大小写。

SN  –k  MyCompany.keys       生成一个包含公钥/密钥对的文件

查看实际的公钥如下图:



 

SN.exe程序未提供任何方式来显示私钥(原因很明显)

第二步:简单的创建一个强命名程序集

csc /keyfileMyCompany.keys  Program.cs

C#编译器看见这个开关,就会打开指定的文件,使用私钥对程序集进行签名,并在清单中嵌入公钥。

注意:只能对包含清单的程序集文件进行签名,程序集的其它文件不能显示签名。

VS2005中的项目“属性”的“签名”选项设置。

默认的哈希算法是SHA-1算法。



  全局程序集缓存(Global Assembly Cache GAC

一个程序集要由多个应用程序访问,就必须把它放到一个已知的目录中,CLR在检查到对程序集的一个引用时,会自动检查该目录C:\Windows\Assembly,该目录就称为GAC

GAC目录是结构化的:其中包含大量子目录,并用一个算法来生成这些子目录的名称。永远不要采取手动方式将程序集文件复制到GAC目录,该使用工具GACUtil.exe

        把程序集文件安装到GAC中,会损害简单安装、备份、还原、移动和卸载应用程序的目标,所以尽量避免全局部署,尽量使用私有部署。

GAC的内部结构

C:\Windows\Assembly\GAC                1.01.1版本创建的程序集

C:\Windows\Assembly\GAC_MSIL   包含CLR2.0版本创建的程序集,IL,有3264

C:\Windows\Assembly\GAC_32         LR2.0版本创建的程序集,IL和本地x86代码

C:\Windows\Assembly\GAC_64         LR2.0版本创建的程序集,IL和本地x64代码

 GAC中搜索一个程序集时,CLR会判断应用程序当前在什么类型的进程中运行,选\AC_32还是\AC_64;如果没找到,就检查\AC_MSIL;如果还没找到,就检查\GAC

GAC的主旨是容纳一个程序集的多个不同版本,但它加载生成和测试时使用的那个版本,即使有新的版本,也不会加载它。

在生成的程序集中引用一个强命名程序集

CSC.exe会尝试在以下目录中查找程序集:

1.       工作目录

2.       包含CSC.exe本身的目录,其中也包含CLR DLL

3.       使用/lib编译器开关指定的任何目录

4.       使用LIB环境变量指定的任何目录

安装.NET Framework 时,实际会安装Microsoft的程序集文件的两套副本。一套副本安装到编译器/CLR目录,另一套安装到一个GAC子目录中。编译器/CLR目录中的文件便于生成程序集,而GAC中的副本便于在运行时加载。

CSC.EXE之所以不在GAC中查找引用的程序集,是因为必须为程序集文件指定一个冗长的、难以记忆的路径。

强命名程序集能防范篡改

程序集安装到GAC时,系统对包含清单的文件的内容进行哈希处理,用公钥对PE文件中嵌入的RSA数字签名进行解除,把哈希值和解除后的值进行比较,一致,说明未被篡改。系统还会对程序集的其他文件的内容进行哈希处理,并将哈希值与清单文件的FileDef表中存储的哈希值进行比较。




 

posted on 2007-11-22 01:47  Sandwi  阅读(1128)  评论(4编辑  收藏  举报

导航