1. Strong Name Summary
包含:simple text name, version number, and culture information,plus a public key and a digital signature.
优点:
- 确保的assembly的唯一性。因为每家公司都可以生成自己的private key。
- 避免DLL hell。 只有你自己才能生成DLL的子版本。
- 防篡改。
缺点:如果是私有部署,性能有所损耗。因为每次加载assembly时都进行把签名用公有密钥解密得出hash code。同时也对DLL进行哈希得出hash code。比较两个hash code。
约束:如果assembly是强命名,那么它引用的assembly必须也是强命名,否则它的功效就会失效。
2. Hashes and Signing
2.1. Hanshes:将assembly用哈希算法生成唯一的单向(不可解密)的hash code。
当创建强命名程序集时,程序集的FileDef清单元数据表包含所有组成程序集的文件列表。当每个文件的名称添加到清单时,文件的内容被转换成散列值,该散列值和文件名一起也被存储在FileDef表中。
在生成包含清单的PE文件之后,PE文件的全部内容(除了所有Authenticode Signature,程序集的强命名数据和PE头校验和)都被转换成一个散列值。这里的散列算法也为SHA-1并且不能改变。
由于公有密钥过于庞大,如果一个程序集引用了多个程序集,文件将会变得很大。因此微软将公共密钥转换成散列值,并取其最后8个字节作为公共密钥标识,存储在AssemblyRef表中。
为何达到了防止篡改:因为hashcode需要校验,会再次生成散列值,再与原来的保存的散列值比较,相同则没有被修改过,这就达到了防止篡改。
hashcode校验有两个情况:1. 私有部署,每次加载assembly都要校验。2. 公有部署,也就是部署到GAC,就是每个assembly加入GAC时校验,以后加载不再校验。
2.2. Signing:
但是又如何保证散列值不被别人篡改呢?那就要用到签名了。签名实质上是先用SN.exe生成公有密钥和私有密钥。
散列值由发布者的私有密钥进行签名,生成的RSA数字签名存储在PE文件的一个保留区域(不包括在散列值的计算中)。CLR头和PE文件将被更新以反映数字签名已经嵌入文件中。
到hash code需要校验时再用保存在assembly的公有密钥进行解密。
通俗点说:签名是对hashcode进行加密来防止被人篡改。
如何确保你强命名assemly A 引用的 assembly B 不被人篡改呢?
上面提过的约束是:如果assembly是强命名,那么它引用的assembly必须也是强命名。实际上在加引用是,B的公有密钥会保持到A中。
2.3. Delay Sing:
延迟签名也就是在开发测试过程中先不进行签名,等到发布前才签名。
目的是:公司不提供私有密钥给开发和测试人员,只有少数的人掌握。
当然有些东西还是需要的,例如引用这个延迟签名的assembly A的assembly B要保存A的公有密钥,并且GAC允许delay sign 的assembly能够被正确存储。
How to sign C++/CLI assemblies with a strong name
http://www.cnblogs.com/jeffreytan/archive/2005/03/01/110820.html