驱动签名学习

在线数字签名信息解析平台:http://lapo.it/asn1js/#

简述如何通过CryptAPI实现签名的生成,并打到pe文件里,时间戳部分还没实现。

一个有效的pe文件签名示例(在英文版系统下,DbgView.exe的签名信息,在文件资源中查看):

   Countersignatures 里面是时间戳签名。

获取PE文件签名信息的工程:GitHub - leeqwind/PESignAnalyzer: This program can retrieve signature information from PE files which signed by one or more certificates on Windows. Supporting multi-signed (nested) infomation and certificate-chain.

下面是通过PESignAnalyzer获取的一个有效的签名信息

参考图片中的签名,签名信息包含有时间戳,版本,摘要算法,后面跟着3小块证书信息。可以看出证书的来源

(2020-10-13)注意:如果是驱动文件签名,最后一个证书必须是微软要求的,可用于内核代码签名的ca证书。该证书列表在下链接中:用于内核模式代码签名的交叉证书 - Windows drivers | Microsoft Docs。如果没有按照微软的签名要求来,签名完成的文件即使通过右键--文件资源查看,数字签名正常,驱动在加载的时候依然会提示错误。

issuer是颁发者,subject是颁发给。Mirosoft Code Verification Root 颁发给 VeriSign Class 3 Public Primary Certification Authority - G5 颁发给 VeriSign Class 3 Code Signing 2010 CA 颁发给 Qihoo 360 Software (Beijin) Company Limited。

编程实现细节:

签名的存放信息在pe结构中的OptionalHeader中DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY],大小和偏移;

例如:size=0x1000,VirtualAddress=0x8000;表示在文件偏移0x8000处存放安全信息,大小为0x1000,其结构信息参考WIN_CERTIFICATE (wintrust.h) - Win32 apps | Microsoft Docs

签名的生成,一个函数可以搞定SignerSignEx,参考SignerSignEx 函数 - Win32 apps | Microsoft Docs

sys和exe的有效签名是不一样的。微软提供的例子好像只能给app签名有效,给sys签名还是加不上。这个时候用前面的工具查看签名信息,证书信息只有一小块,要补齐另外2块,才是完整的有效驱动签名。补齐另外2块实际上就是把证书来源补齐。

在SignerSignEx成功的基础上ppSignerContext会返回签名信息(是最后有效签名的一部分),用CryptMsgControl(*,*,CMSG_CTRL_ADD_CERT,*)添加另外2个证书信息(这个的自己去找了),得到最后有效的签名(注意长度以8字节对齐)

得到完整的签名后,按照相关格式填到pe文件中,最后计算整个文件的checksum 保存到OptionalHeader中CheckSum中。

大功告成。

这个方法是学习wosigncode(比signtool好用多了)。还有另外一种方法是学习signtool的c++ - How to Sign an EXE with Additional Certificates using CryptoAPI and SignerSign - Stack Overflow,但是我按照上面的提示没得成功,可惜了。

补充:如何完善证书链中的证书信息?

证书链的构成:spc(软件颁发者证书)--->Intermediate CA(中级证书颁发机构的证书)--->root   CA(根证书)

一般spc包含在.pfx的文件中,这个应该比较好获取;Itermediate CA证书包含spc证书颁发者的信息,获取spc对应的Intermediate CA 可以通过调用CertGetCertificateChain(*),然后去CURRENT_USER ,“Ca”下找;root CA 可以去网上下,root CA 只有20几个。

在mmc中查看Intermediate CA

最后是可恶的 时间戳:

为了避免签名被篡改,得给签名再来个签名---时间戳.时间戳签名的组成是(时间戳服务器上的时间+第一个签名的摘要(message digest+)的hash,再由时间戳证书对hash进行签名,最后将结果返回给时间戳的请求者 。具体的细节可以参考网上公开的时间戳服务器(c#写的)和CryptMsgVerifyCountersignatureEncoded()的实现。

补充(2020/9/2):

时间戳属于 CounterSignature 的一种,CounterSignature指 副署,会签,也就是交叉签名。一般对文件进行签名之后,需要将签名数据通过网络发送到公开的时间戳服务器进行会签。时间戳的意义:1.确保当前时间点,签名的证书是有效的(证书使用是有时间限制的,要收费)2.如果没有时间戳,假如证书a对文件b进行了签名,a证书的有效期2010-2012;那么在2010-2012文件b在进行签名验证时会通过,在其他时间则不能通过签名验证;如果签名之后打上时间戳,b文件在有效期之外也可以通过签名验证。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值