CLR用数字签名的方式防止程序集发布后被人篡改,也可以确定发布人,这个方法就是使用公/私钥对,然后对程序集所有模块取一个哈希生成一个数字签名放在程序集的元数据中。
1、创建公/私钥对
创建公/私钥对有两种方式,一种是通过Visual Studio 命令提示框执行sn -k 密钥.snk方式创建私钥文件;(Visual Studio 命令提示框 最好以管理员方式打开)
第二种是在VS中,在创建的项目名称上右键,打开属性窗口,找到签名栏。
创建出的私钥里包含了公钥和私钥信息,其中私钥436个字节,公钥由128字节内容和一个32字节的头组成。
2、使用公钥进行签名
一般在开发的时候,都会使用延迟签名的功能,因为公钥是公开的,私钥是非公开的,而且私钥一般是保密的。
在项目调试时不能一直申请使用私钥签名,所以微软允许只使用公钥签名,公钥可以从私钥中获取;
通过VS命令提示框中执行sn -p company.snk Company.public.snk命令提取公钥文件;
指定签名文件为生成的公钥文件;
在延迟签名之后的程序是不能直接运行的,如果直接运行,会出现错误。提示强名称验证失败。
我们需要使用sn的-Vr命令告诉CLR在加载程序时,不要对哈希值进行检查:sn -Vr signTest.exe。其中signTest.exe为目标程序集,是C#生成的exe或dll文件。
这个命令只需要执行一次,意思是在本机的CLR上注册一下,不要验证程序集安全性,然后在运行程序就没问题了。
如果需要注销只需执行命令 sn -Vu signTest.exe 即可。
3、使用私钥进行强签名
程序开发完成要进行发布时,调用 sn -Ra signTest.exe Company.snk对程序集进行强签名,这样就拥有防篡改的保护了。
强签名之后 ,CLR每一次加载运行都回验证程序集,如果哈希值与之前生成的公/私钥不匹配,则认为程序已经被篡改,就会阻止程序运行。
4、使用public key token
很多时候可以看到这种引用 SignTestBll.dll,Version=1.0.2.0,Culture=neutral,PublicKeyToken=07f814c98e5c0897
这个PublicKeyToken是干什么的呢?
它其实就是根据公钥的哈希值计算出来的,用来标识一个dll文件的唯一性。
首先使用SHA1算法从公钥等到它的哈希值,取出这个哈希值最后的8个字节,然后把这8个字节倒排一下,就能得到了。