织梦CMS - 轻松建站从此开始!

罗索实验室

捣腾数字签名

jackyhwei 发布于 2018-04-27 15:01 点击:次 
正好这几天稍微闲暇一些,在好奇心的驱使下便开始捣鼓起数字签名来。经过一天终于有点收获,大致理解数字签名是怎么一回事,也对公司代码的那两块地方比较理解了,于是做个小结。
TAG: 数字签名  证书  VeriSign  

  昨天在公司的代码中,看见一个VC项目的Post Build Step会用signtool给项目生成的exe添加数字签名,而exe的某块代码会调用WinVerifyTrust这个Windows API来验证exe自己的数字签名。正好这几天稍微闲暇一些,在好奇心的驱使下便开始捣鼓起数字签名来。经过一天终于有点收获,大致理解数字签名是怎么一回事,也对公司代码的那两块地方比较理解了,于是做个小结。

 

  首先推荐读读《算法导论》31.7节The RSA public-key crptosystem的第一小节:Public-key cryptosystems,对公钥密码系统的框架做个了解,当然也可以到网上搜类似的介绍性文章。这里不用知道任何数学公式,但要理解整个系统的逻辑流程和设计思想,尤其要理解私钥、公钥的概念,并且要知道:一个消息经公钥和私钥两次编码还是消息本身,且既可以用公钥先编码,也可以用私钥先编码。在这里我还弄明白了:虽然加密和数字签名这两种手段都可以基于同样的公钥密码系统,但它们的目的和工作流程是不一样的——前者是防窃听,后者是验真伪。

 

  接下来就是捣腾Windows上的数字签名工具,实践一下。signtool是Windows SDK自带的命令行工具,用于对文件进行数字签名,也可用于验证文件和时间戳文件中的签名。公司的那个VC项目使用了如下命令对exe进行数字签名:

 

signtool /a <生成的exe>

 

  不过我用同样的命令在自己家电脑上给一个exe签名,却总是得到“SignTool Error: No certificates were found that met all the given criteria”的错误。捣鼓了半天才知道,如果是自己测试的话,要先用makecert、cert2spc和pvk2pfx制作一个同时包含私钥和公钥的pfx格式的证书文件,然后用pfx文件给exe签名,或者将pfx导入证书库中,让signtool自己去搜可用的证书。可参考《makecert制作数字证书》这篇文章。为了模拟公司项目,我采用了导入证书库的做法,具体来说是这样:

 

  1、用makecert制作自己的根证书:

 

E:\Temp>makecert -n "CN=ZzxiangRoot" -r -sky signature -sv ZzxiangRoot.pvk ZzxiangRoot.cer
Succeeded

 

因为我明确是要给二进制文件制作签名,所以要加上-sky signature选项。于是E:\Temp目录下就回生成两个文件:私钥证书ZzxiangRoot.pvk和公钥证书ZzxiangRoot.cer。

 

2、用cert2spc将公钥证书转换为软件发布者证书,即spc文件:

 

E:\Temp>cert2spc ZzxiangRoot.cer ZzxiangRoot.spc
Succeeded

 

3、用pvk2pfx将公钥证书和私钥证书合并成一个PFX格式的证书文件:

 

E:\Temp>pvk2pfx -pvk ZzxiangRoot.pvk -spc ZzxiangRoot.spc -pfx ZzxiangRoot.pfx

 

4、双击ZzxiangRoot.pfx将其导入证书库中。在“证书导入向导”中,一路点击“下一步”,直到“证书存储”步骤,选择“将所有的证书放入下列存储”:

 

 

点击“浏览”,在弹出的对话框中选择“个人”->“确定”。

 

 

为什么要选择“个人”呢?可以参见signtool的sign子命令的/s选项的说明:“指定要在搜索证书时打开的存储区。 如果未指定该选项,则打开My存储。”这里的“My”就是“个人”。

 

然后就可以一路“下一步”到导入完成了。我们可以到计算机的管理控制台确认。在开始菜单中搜索并运行mmc。在mmc界面中,选择“文件”->“添加删除管理单元”。在弹出的“添加删除管理单元”对话框中,在左边的“可用的管理单元”中选择“证书”:

 

 

点击中间的“添加”按钮,在弹出的对话框中选择“我的用户帐户”或“计算机用户帐户”,再点击“完成”:

 

 

就将“证书”节点添加到“所选管理节点”中了:

 

 

点击“确定”,回到管理控制台主界面中,在左边的树控件中展开“证书 - 当前用户”->“个人”,选择“证书”节点,就可以看见已经导入的ZzxiangRoot证书。

 

双击ZzxiangRoot,可以看见证书对话框里写着“您有一个与该证书对应的私钥”。对话框里还写着“此CA根目录证书不受信任。要启用信任,请将该证书安装到‘受信任的根证书颁发机构’存储区”。后面会讲到这一点。

 

5、现在可以使用signtool命令给exe签名了:

 

E:\Temp>signtool sign /a Test.exe
Done Adding Additional Store
Successfully signed: Test.exe

 

可以加上/v查看更细致的输出:

 

E:\Temp>signtool sign /a /v Test.exe
The following certificate was selected:
    Issued to: ZzxiangRoot
    Issued by: ZzxiangRoot
    Expires:   Sun Jan 01 07:59:59 2040
    SHA1 hash: 3361BBBD366687FD80B201F1346561C6E4936263


Done Adding Additional Store
Successfully signed: Test.exe


Number of files successfully Signed: 1
Number of warnings: 0
Number of errors: 0

 

  接下来就是要验证exe的签名。按照公钥密码系统的设计思路,这一步可以在任意机器上进行。公司代码用的是WinVerifyTrust函数。其实也可以继续用signtool工具,命令格式是

 

signtool verify /pa <需要验证的exe>

 

  注意必须要加上/pa选项,否则signtool会使用针对Windows驱动程序的签名验证策略。

 

  不过现在直接用signtool verify /pa Test.exe的话,会得到“SignTool Error: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider”的错误。这是因为验证用的计算机没有将ZzxiangRoot公钥证书添加到之前提到的“受信任的根证书颁发机构”。要做这一步的话,需要将公钥证书ZzxiangRoot.cer拷贝到验证机上,然后双击该cer文件,在弹出的证书对话框中选择“安装证书”。接下来和之前的导入证书操作一样,只是在“证书存储”这一步,需要选择将证书存储在“受信任的根证书颁发机构”存储区,而不是之前的“个人”存储区中。

 

  现在可以进行验证了:

 

E:\Temp>signtool verify /pa Test.exe

Successfully verified: Test.exe

 

也可以加上/v查看更细致的输出:

 

E:\Temp>signtool verify /pa /v Test.exe


Verifying: Test.exe
Hash of file (sha1): 8D3C56FBE8BB11FB760B729FF8F801DDBA7C3B59


Signing Certificate Chain:
    Issued to: ZzxiangRoot
    Issued by: ZzxiangRoot
    Expires:   Sun Jan 01 07:59:59 2040
    SHA1 hash: 3361BBBD366687FD80B201F1346561C6E4936263


File is not timestamped.


Successfully verified: Test.exe


Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 0

 

  使用WinVerifyTrust函数进行验证的方法可以参见MSDN的这个例子。这个例程可以直接拷贝下来用的,只是需要注意,要将它作为C++文件来编译,而不是纯C文件,否则会编译不过。

 

  说起来真是挺搞笑。虽然我的大学宣称自己的特色是信息安全,但大学毕业后五年来,这还是我第一次认真研究信息安全相关的技术。

(zzxiang1985)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201804/17531.html]
本文出处:CSDN博客 作者:zzxiang1985
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
相关文章
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容