2. 驱动签名基础

驱动签名是Windows驱动程序安全性的基石,也是WHQL认证与安全启动调试的前提条件。本章从数字签名底层原理出发,逐步深入到Authenticode签名机制与交叉证书签名的实际应用,帮助开发者建立完整的驱动签名知识体系。

2.1 数字签名原理

数字签名并非简单的加密,而是基于公钥基础设施(PKI)的完整性验证与身份认证机制。驱动签名主要解决三个核心问题:

  • 身份认证:确认驱动发布者的真实身份
  • 完整性校验:确保驱动文件未被篡改
  • 不可否认性:发布者无法否认其签名行为

数字签名的核心流程包含签名生成与签名验证两个阶段,其工作原理如下图所示:

数字签名核心原理流程图 签名生成阶段 驱动文件(.sys) 哈希算法(SHA256) 文件哈希值 私钥加密 数字签名(加密后的哈希值) 签名验证阶段 驱动文件 + 签名 哈希算法(SHA256) 计算出的哈希值 公钥解密 对比:一致则验证通过
关键概念:数字签名使用非对称加密,私钥仅签名者持有,公钥随驱动分发。验证时,系统使用公钥解密签名得到原始哈希值,再与文件实际哈希值比对,两者一致则证明文件未被篡改且签名者身份可信。

2.2 Authenticode签名

Authenticode是微软专为Windows可执行文件(包括驱动)设计的数字签名技术。它基于PKCS #7标准,将数字签名嵌入到PE文件结构中,形成嵌入式签名。对于驱动程序,Authenticode签名是WHQL认证与安全启动验证的基础。

2.2.1 Authenticode签名结构

Authenticode签名在PE文件中的存储位置与结构如下表所示:

PE节区 签名内容 说明
Certificate Table PKCS #7签名数据 位于PE文件末尾,通过数据目录索引
Signer Info 签名者证书链 包含签名证书、中间CA证书、根证书
Authenticated Attributes 文件哈希、时间戳等 受签名保护,不可篡改
Unauthenticated Attributes 计数器签名等 不受签名保护,可追加

2.2.2 签名工具与命令

Windows驱动开发中最常用的Authenticode签名工具是SignTool.exe,它随Windows SDK发布。以下是驱动签名的标准命令示例:

# 使用SHA256哈希算法对驱动进行签名
signtool sign /fd SHA256 /a /s MY /n "Your Company Name" /t http://timestamp.digicert.com driver.sys

# 使用交叉证书签名(适用于Windows 7/8兼容)
signtool sign /fd SHA256 /ac "cross-cert.cer" /s MY /n "Your Company Name" /t http://timestamp.digicert.com driver.sys

# 验证驱动签名
signtool verify /v /kp driver.sys
重要提示:从Windows 10 1607版本开始,所有内核模式驱动程序必须使用SHA256哈希算法签名,SHA1签名已被弃用。同时,签名时间戳必须使用RFC 3161标准的时间戳服务器。

2.2.3 Authenticode签名验证流程

Windows系统在加载驱动时,会执行以下Authenticode验证步骤:

  1. 解析PE文件:定位Certificate Table,提取PKCS #7签名数据
  2. 构建证书链:从签名者证书回溯到受信任的根证书颁发机构(CA)
  3. 验证证书有效性:检查证书是否过期、是否被吊销(CRL/OCSP)
  4. 计算文件哈希:对PE文件内容(排除Certificate Table)计算SHA256哈希
  5. 比对哈希值:将计算出的哈希值与签名中的哈希值进行比对
  6. 检查时间戳:验证时间戳签名是否有效,确保签名在证书有效期内完成

2.3 交叉证书签名

交叉证书签名是解决证书链信任问题的关键技术。当驱动签名证书由非微软根CA颁发时,需要通过交叉证书将签名证书链桥接到微软根CA,以确保在Windows系统上被信任。

2.3.1 为什么需要交叉证书

Windows系统预置了受信任的根证书列表。如果驱动签名证书的根CA不在该列表中,系统将无法验证签名链,导致驱动加载失败。交叉证书的作用如下:

  • 桥接信任:将第三方CA的根证书链接到微软根CA
  • 兼容旧系统:Windows 7/8等系统可能未包含较新的CA根证书
  • 满足EV要求:扩展验证(EV)代码签名证书需要交叉证书支持

2.3.2 交叉证书签名流程

交叉证书签名的完整流程如下图所示:

交叉证书签名架构图 微软根CA(受信任) 交叉证书(桥接) 第三方CA(如DigiCert) EV代码签名证书 已签名驱动文件 信任链说明 1. 微软根CA预置在Windows中 2. 交叉证书由微软根CA签发 3. 第三方CA由交叉证书担保 4. EV证书由第三方CA签发 5. 驱动签名链完整可验证 验证路径: 驱动 → EV证书 → 第三方CA → 交叉证书 → 微软根CA → 信任成功

2.3.3 交叉证书获取与使用

交叉证书通常由CA机构提供,或从微软官方下载。以下是使用交叉证书进行签名的完整步骤:

  1. 获取交叉证书:从CA机构或微软下载对应的交叉证书文件(.cer格式)
  2. 安装交叉证书:将交叉证书导入到本地计算机的“受信任的根证书颁发机构”存储区
  3. 执行签名:使用SignTool的/ac参数指定交叉证书文件
  4. 验证签名:使用signtool verify /v /kp命令验证签名链完整性
最佳实践:在WHQL认证提交前,建议使用交叉证书对驱动进行预签名测试。使用signtool verify /v /kp命令时,如果输出包含“Signing Certificate Chain Verified”且无错误,说明签名链完整可信。

2.4 签名类型对比

不同类型的驱动签名在应用场景、验证要求和兼容性上存在差异,下表总结了主要签名类型的核心区别:

签名类型 应用场景 验证要求 兼容性
测试签名 开发调试阶段 需启用TESTSIGNING模式 仅限开发环境
Authenticode签名 正式发布驱动 证书链完整、时间戳有效 Windows Vista+
交叉证书签名 第三方CA签名的驱动 交叉证书桥接微软根CA Windows 7+
WHQL签名 通过WHQL认证的驱动 微软交叉签名+WHQL测试 所有Windows版本
ELAM签名 早期启动反恶意软件驱动 特殊ELAM证书+微软审核 Windows 8+

2.5 常见签名问题与调试

在驱动签名过程中,开发者常遇到以下问题,需要掌握对应的调试方法:

  • 签名验证失败(0x80096010):证书链不完整,缺少中间CA证书或交叉证书
  • 时间戳无效(0x800B0101):时间戳服务器不可达或时间戳证书过期
  • 哈希算法不匹配(0x80070032):使用了SHA1签名但系统要求SHA256
  • 证书吊销(0x800B010C):签名证书已被吊销,需重新申请证书
调试建议:使用signtool verify /v /pa命令可以查看详细的签名验证日志。如果遇到证书链问题,使用certmgr.msc检查证书存储区,确保所有中间证书和交叉证书已正确安装。