.Net中的强程序集命名

1. 引

      RSA算法以公/私钥为基础. 数据经公钥加密后只能通过私钥解密, 之亦然.

      比如, A传递信息给B, 我们需要2方面的保证: 信息安全和身份确认. 在A端, 我们可以将信息用B的公钥加密, 然后将签名用A的私钥加密; 在B端, 用B的私钥解密信息, 用A的公钥解密签名.

2. 概念

      强程序集名包含4部分, 简名, 版本号, 语言, 签名. 其中签名以公钥形式标注, 用来解密由私钥加密的程序集散列, 同一签名表示同一来源. 应用强程序集命名一般为了达到2个目的: 唯一标识GAC中的程序集; 防止程序集篡改. 和防止组件方法调用无任何关系.

3. 原理

      CLR不可加载或运行签名不全(仅有公钥)的程序集.

      [

      签名机制
      1. 用SN.exe 生成一个key文件, 这个key文件包括一个public key 和一个private key;
      2. 用这个key文件签名assembly时, 编译器将用private key签名程序集, 并将public key嵌入manifest中;
      3. 编译器哈希manifest中所有的assembly内容, 并将此哈希值各自assembly的FileDef Table中; 
      4. 当如上3步处理后, 编译器将哈希PE文件的整个内容(除authenticode signature,强名称数据, PE头), 然后将此哈希值用private key签名, 得到RSA数字签名;
      5. 将此数字签名嵌入到PE文件的CLR头。

      防修改机制
      1. 当签名后的assembly安装到GAC, 系统会哈希PE文件(同签名),得到哈希值;
      2. 系统读取PE文件中CLR头中的RSA签名, 并用public key(包含在manifest中)解密;
      3. 比较第1步得到的哈希值和第2步得到解密值是否一致, 从而判断其是否被修改。

      ]

4. 由于私钥的重要性, 不适合在开发等阶段持续可访问. .Net中提供了延迟签名:

      [

      1. 从公共/私有密钥匙对中提取公共密匙。为了提取公共密匙,也就是存储公共/私有密匙对,你可以使用强名工具,命令行如下:

      sn.exe -p MyKeyFile.snk MyPublicKeyFile.snk

      2. 将包含公共密匙的文件分发给公司所有的开发者,同时将包含公共/私有密钥匙对的文件安全存放。

      3. 在组件信息文件中包含公共密匙的文件,并注明延迟签名。

      [assembly: AssemblyDelaySign(true)] 
      [assembly: AssemblyKeyFile("..\\..\\MyPublicKeyFile.snk")] 
      如果你使用组件连接工具,而非Visual Studio .NET,你可以使用/delaysign命令行来表明延迟签名。

      4. 如果你把组件保存在全局程序集缓存(GAC)中,应关闭对组件的验证,因为GAC默认验证每个组件的强名。如果组件没有采用私有密钥匙来签名,这个验证将会失败。因此,出于开发和测试的目的你可以输入如下的命名行:

      sn.exe -Vr MyFile.dll (需要定位文件, 注意文件存放目录, 并提升权限操作)

      5. 这样,你就可以在开发和测试的时候很自由的使用组件

      6. 当部署一个延迟签名的组件的时候,你必须通过私有密匙来给它签名。

      sn.exe -R MyFile.dll MyKeyFile.snk

      7. 最后,你必须通知GAC重新开启对组件的验证。命名行如下:

      sn.exe -Vu MyFile.dll

      ]

5. 其他.

    通常程序集的PublicKeyToken同其内部签名文件的PublicKeyToken, 可以执行<sn.exe -T MyFile.dll>查看.

posted @ 2009-06-25 15:21  Tyrael  阅读(431)  评论(0编辑  收藏  举报