第三章 共享程序集和强命名程序集

来源:互联网 发布:免费远程教学软件 编辑:程序博客网 时间:2024/04/28 01:23

3.1 两种程序集,两种部署

   CLR有两种程序集,弱命名程序集和强命名程序集,二者基本一样,区别:强命名程序集时用发布者的公钥/私钥对 进行了签名,唯一性的标识了程序集的发布者。弱命名程序集只能私有部署,强命名程序集可以使用全局部署,也可以私有部署。

3.2  为程序集指派名称

    一个强命名的程序集包括4部分重要属性,标志唯一:一个无扩展名的程序集,一个版本号,一个语言文化标志,一个公钥publickey。此外,还使用发布者的私钥进行签名
        MyTypes,Version=1.0.8123.0,Culture=neatral,PublicKeyToken=xxxxxxxxxxxxxxxx(公钥标记)

    MS使用公钥/私钥加密技术,这样,没有两家公司有相同的公钥/私钥对(除非他们共享公钥/私钥对)。
    
    使用反射获取强命名程序集的PublicKeyToken

    创建强命名程序集的步骤:
        1.生成公钥/私钥对:使用SN命令,这个命令所有开关都区分大小写
            SN    -k    MyCompany.keys
            ——这里MyCompany.keys是创建的文件名

        2.将原有程序集升级为强命名程序集
            csc    /keyfile:MyCompany.keys    app.cs
            ——这里,app.cs是包含清单表的文件,不能对不包含清单表的文件签名。C#编译器会打开MyCompany,使用私钥对程序集进行签名,并在清单中嵌入公钥。           

用私钥签名一个文件:是指生成一个强命名程序集时,程序集的FileDef清单中列出了包含的所有本件,将每个文件名称添加到清单中,文件的内容都会根据私钥进行哈希处理,得到的哈希值与文件名一起存入FileDef中。这个哈希值称为RSA数字签名。

最终,生成的包含清单的PE32文件,其中会含有RSA数字签名和公钥

补充1:签名默认使用SHA-1算法,也可以使用别的算法,通过AL命令的/algid开关指定。
     
补充2,还可以使用SN命令,在原有基础上,得到只含公钥的文件并显示:
            SN    -p    MyCompany.keys    MyCompany.PublicKey
            ——这里MyCompany.PublicKey是创建的公钥文件名
            SN    -pt   MyCompany.PublicKey
            ——显示公钥与公钥标记   

补充3:在IL中,Local对应于Culture

补充4:公钥标记是公钥的最后8个字节。
              AssemblyRef中存的是公钥标记,AssemblyDef存的是公钥。

3.3 GAC全局程序集缓存

    GAC一般在C:\Windows\Assembly,结构化的,有很多子目录。
        使用Windows Explorer shell扩展来浏览GAC目录,这个工具是在安装Framework时附带的。
        不能使用手动方法复制程序集文件到GAC,要使用GACUtil命令。
        只能安装强命名程序集到GAC中,而且要有Admin/PowerUser权限。
    
    GAC的好处是可以容纳一个程序集的多个版本。每个版本都有自己的目录。缺点是违反了简单安装的原则。

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

第2章有讲到,对于不完整路径,csc编译时目录查找顺序:
    1.工作目录(要编译的cs文件所在)
    2.系统目录(csc.exe所在,同时也包括CLR DLL)
    3./lib开关指定的目录
    4.LIB系统变量指定的目录

安装Framework时,会安装.NET程序集两套副本,一套在编译器/CLR目录——便于生成程序集,另一套在GAC子目录——便于在运行时加载它们。编译时并不去GAC中查找。

3.5 强命名程序集能防范篡改

在安装强命名程序集到GAC时,系统对包含清单的文件内容进行哈希处理,并将这个值与PE32文件中嵌入的RSA数字签名进行比较,如果一致,就再去比较其他文件内容(也是哈希处理在比RSA签名)。一旦有一个不一致,就不能安装到GAC。

如果强命名程序集安装在GAC以外的目录,则会在加载时比较签名。

3.6 延迟签名(部分签名)

开发阶段会使用到这个功能
允许开发人员只用公钥来生成一个程序集,而不需要私钥。
编译时,会预留一定空间来存储RSA数字签名,不对文件内容进行哈希处理。CLR会跳过对哈希值的检查。以后可
以再对其进行签名。
步骤如下:
1.生成程序集:csc /keyfile: MyCompany.PublicKey /delaysign: MyAssembly.cs
2.跳过对哈希值的检查: SN.exe -Vr MyAssembly.dll
3.准备私钥,再次进行签名:    SN.exe -R MyAssembly.dll MyCompany.PrivateKey
4.再次延迟签名:    SN.exe -Vu MyAssembly.dll

3.7 私有部署强命名程序集

强命名程序集如果不在GAC中,每次加载都要进行验证,有性能损失。
还可以设计为局部共享强命名程序集,指定配置文件的codeBase即可。

3.8 运行库如何解析类型引用

    在TypeRef中查找类型引用的纪录,发现其强签名,然后定位这个程序集的所在位置:会在以下三个地方查找:
        1.同一个文件:编译时就能发现(早期绑定)
        2.不同的文件,但同一个程序集:在FileRef表中
        3.不同的文件,不同的程序集:这时要加载被引用的程序集,从中查找

注:AssemblyRef使用不带扩展名的文件名来引用程序集。绑定程序集时,系统通过探测xx.dll和xx.exe来定位文件。
        ModuleDef,ModuleRef,FileDef使用文件名及其扩展名来引用文件。

注:在GAC中查找程序集时,除了名称,版本,语言文化和公钥,还需要CPU体系结构,而且是先根据这个体系结构查找


原创粉丝点击