最近在写一个windows内核驱动,接触了数字签名这方面的内容,虽然老早就了解过,但是一直没机会实践。正好现在甲方爸爸提供资金,终于有机会折腾了!然而由于网上教程非常之少,大部分需要自己读文档踩坑,这边就记录一下。

参考文章

网上教程比较少,可以先看看,以官方文档为主。

证书申请

代码签名证书是什么就不多说了网上都能找到,这边主要有两类:标准代码签名证书和EV扩展签名证书。它们都能签名可执行文件防止误报,区别在于只有EV扩展签名证书才能对驱动签名。这里由于我们要签名驱动所以选择了EV证书,至于厂商看了一圈发现国内代理加价还是很严重的,基本上是国外同等证书的2-10倍。这边省点预算选择了ssl.com的EV证书,大概在三年700多刀属于是正常价格了。

申请过程没什么坑,提交公司相关资质就行,全程也有客服24小时服务,非常的nice。需要注意一点就是如果不想每个月掏100刀订阅云签名服务就必须将证书保存在yubikey上,这边也有两种方式。

申请证书时一并购买

这种方式比较省事,下单时添加一个yubikey就行(价格略高于官网价),寄到手的话里面证书什么的就已经弄好了不用管了(不知道国内在不在邮寄范围,不在的话可能需要转运服务)。

自有yubikey

ssl.com也支持自有yubikey(需要支持FIPS的版本),由于我手上正好有一个就不用再等快递了,然后根据官方文档导入就行了。注意这里有个坑,如果你直接照着搞最后签名的时候会出现类似 Error information: "Error: SignerSign() failed." (-2146435071/0x80100001) 的错误,这是由于你下载的证书实际上是云签名的证书而不是attestation的。根据与客服的交流,正确流程应该是这样:

  1. 先照文档做到3.10步,也就是到你的Attestation Certificate上传成功这步。
  2. 联系客服认证,让他们根据你上传的证书给你最终颁发正确的证书。
  3. 等待颁发成功后从文档3.10开始继续做,注意下载的证书应该是End Entity中yubikey的证书而不是eSigner的。

这样按照文档做完就可以正常签名了,另外注意一点,如果使用signtool进行签名最好使用 /sha1 参数指定证书,否则自动选择可能会选到intermediate证书导致失败。

如果要取消eSigner请先做完上面的步骤并本地测试签名,成功后按照官方文档取消订阅即可,务必确认End Entity中有除了eSigner以外的证书,否则取消订阅后就签不了名了需要花钱重新颁发。

证书测试与驱动签名

拿到证书后就可以用signtool签名了,可以避免杀软的误杀和SmartScreen的检查,然而这些都是针对文档和可执行程序的,对于系统驱动还需要进一步的认证。

根据微软文档,测试的话可以采用启动选项禁用驱动签名检查或者 Bcdedit.exe -set TESTSIGNING ON 启用测试模式。需要注意的是,如果使用启动选项的方式,那么无论驱动的签名是什么都可以加载,而测试模式也需要有测试签名,如果是其他签名则还是会拒绝加载。换言之,在测试的时候如果sys文件用的是自己的EV签名,还是要开机时按F8进入关闭驱动签名强制的模式,否则将无法加载。

如果想发布驱动的话还需要通过WHQL认证,根据微软文档,交叉签名在2021年就已经被弃用了,所以想省事是不行滴……

主要认证方式也有两种:attestation-signing和HLK/HCK认证。

attestation-signing

这个应该是最方便的,但是注意在win7上没法用,如果不支持win7可以用这种方法,参考

HLK/HCK认证

这玩意儿非常之弱智,网上也是复制粘贴的东西搞半天还是一知半解,先根据我的理解简单介绍一下几个名词。

  • HLK:微软的一套测试框架,win10以上驱动需要通过测试以证明稳定性。
  • HCK:HLK的旧版本,win7驱动需要通过这个测试。
  • HLK/HCK Controller:测试的服务端,用于下发测试任务给客户端并收集结果。
  • HLK/HCK Studio:测试管理界面。
  • HLK/HCK Client:实际跑测试的客户端。

如果驱动需要win7-win11的支持那么必须都通过才行,我这边只要win7支持而已。用Virtual Box虚拟机搭了一套测试平台,需要下载以下几个系统安装包,注意所有系统请务必选择英文版以避免乱七八糟的问题,同时根据微软描述,64位系统不能加载32位驱动,因此需要32位系统测试32位的驱动程序:

  • Windows Server 2008 R2 x64(English)
  • Windows Server 2012 R2 x64(English)
  • Windows 7 SP1 Enterprise x86(English)
  • Windows 7 SP1 Enterprise x64(English)

由于虚拟机之间需要能够访问,因此虚拟机网卡需要使用桥接模式。

HCK认证

这里下载HCK安装包。

HCK服务端建议使用Windows Server 2008 R2英文版,2012也可以但是需要关闭域控,比较麻烦。系统安装成功后在Manager里关闭IE ESC,注意由于证书过期直接安装HCK的话会报错无法下载,可以选择通过安装补丁或者在宿主机上运行安装程序选第二个只下载不安装,然后通过共享文件夹给虚拟机。

安装过程比较漫长,记得一开始需要选择允许开启端口。装完之后就切到win7虚拟机,访问 \\服务端计算机名\\HCKInstall\Client\Setup.exe 输入登录用户密码安装客户端就行了。

注意是计算机名(WIN-XXX)而不是IP地址,在选择网络的时候记得统一选择工作环境或者公共环境,并且允许计算机被发现。

所有东西装好之后就可以进行测试了:

A. 客户端:

  1. 进入关闭签名强制模式。
  2. 把驱动复制到客户端安装。
  3. 使用 sc start [service] 或其他方式运行驱动。
  4. 在“服务”中重启 HCK communication service

B. 服务端:
前置条件:注意服务端需要进行一些配置,否则会在测试时报错,这个我只在帮助文档里翻了半天才找到,没有报错也没有警告,非常的逆天。
具体来讲如果是文件系统驱动的话需要按照下面的建议预先分好区:
info.png
注意如果格式化的时候没有对应的分区格式选项那么就需要通过命令来弄,比如说UDF格式可以通过以下命令:

1
format N: /fs:UDF /q

REFS分区可能对部分驱动来说不是必须的,具体得看HCK给出的测试选项详情。我没有进行这个分区似乎也没报错。

分好区后大概长这样
res.png

  1. 运行HCK Studio,点击右上角Configuration。
  2. 客户端应该出现在默认pool中了,如果没有请尝试A.4或重启客户端/服务端。
  3. 将客户端拖到新建的pool中,右击设置状态为Ready。
  4. 新建一个项目,选择pool后在左侧调整到 driver 栏目,找到你的驱动钩上就好了。
  5. 把想测的选项勾好(一般全钩上就行了),开始测试,然后等个把小时就完工了~

问题排查

一般来说遇到的最常见的问题是自己的驱动没有显示在测试列表里,解决方法可以按照下面的checklist:

  • 确保驱动已经在客户端上运行(即 sc query 为running)
  • 确保在 driver 栏目找不到驱动而不是其他栏目
  • 在HCK Studio的Configuration中删除客户端
  • 关闭客户端 HCK communication service
  • 重启服务端系统
  • 重新开启 HCK communication service

如果还是不行那我也不知道怎么办了……可能微软传统艺能重启几下就行了XD

结果打包

偷偷说一句这玩意儿似乎也就是走个形式,部分测试不通过似乎也并不要紧……当然具体的标准不太清楚,我有一个32位的测试空跑都报错不知道为何,但也不影响最后的认证。

注意一点无论是HCK还是HLK都不支持ecdsa的证书签名(即目前主流EV证书算法),这个需要找客服要到rsa算法的证书才行。如果是ssl.com联系客服会给你颁发一个免费的OV证书,然后生效之后你选择生成RSA算法的证书下载就行了。注意目前yubikey似乎并不打算支持RSA4096,而小于等于2048位的证书申请ssl.com并不能通过。因此这种情况下生成的证书只能用传统的文件形式,不能存储在yubikey里。

测试完了以后在package里面添加上 .cat.inf.sys 三个文件选好locale创建package即可,可以添加两个分别对应32位64位不同版本。注意如果将不想在虚拟机内签名也可以先不签名,然后在其他机器上只安装HCK Studio(几百兆左右很小的一个)就可以打开hckx文件继续签名啦~最后用RSA算法的证书签名即可。

注意 .cat.sys 文件请不要包含任何数字签名,经过测试发现如果sys文件包含了自己的EV签名,最后认证的文件会有两个签名(微软的和你自己的),在某些win7下微软数字签名可能不会生效导致依然无法加载。

微软WHQL认证

这玩意又是一个非常坑的东西,如果有需要还是建议找微软中国的客服全程指导……
如果你想自己搞,可以参考我走的路(

  • 注册成为微软合作伙伴,注意最好用公司域名邮箱免得各种麻烦.
  • 填写各种信息,然后在法律信息这里等待通过,可能需要补充资料。
  • 验证域名所有权,这个是最简单的加个txt解析就行了。
  • 注册微软硬件开发者计划,使用之前认证通过的账户即可。
  • 验证签名,将提供的文件下下来然后用RSA证书(即签名hckx文件的证书)签名后提交。
  • 搞定

在注册微软硬件开发者计划时候可能会遇到无限跳转无法继续的BUG,这个原因很多网上说法不一,不愧是BUG软,建议直接找客服提ticket省时省力(我尝试各种方式无果后还是联系客服了)……除了响应时间薛定谔以外没啥缺点hhh

最后认证就简单了,在微软合作伙伴仪表盘的硬件里面创建一个新的driver提交hckx文件就行了,发布是全自动的大概在30min之内就能下载到有微软签名的驱动啦。

如果需要更新驱动,最简单的方式就是新建一个新提交,原先提交里的update似乎并不是为传统的版本更新服务的,

驱动发布

如果你使用的是windows7 sp1原盘的话那么通过了WHQL认证目前也无法加载,因为现在微软只提供sha1的驱动签名,而sha1签名并不是win7默认支持的。可以参考官方指南,简单来说,需要安装KB4490628和KB4474419这两个更新,可以在Microsoft Update Catalog上下到离线版本,统统整合进软件安装包安装完事!

总结

  1. 读文档
  2. 多踩坑
  3. 问客服