2. 驱动签名基础:数字签名原理、Authenticode签名、交叉证书签名
驱动签名是Windows驱动程序安全性的基石,也是WHQL认证与安全启动调试的前提条件。本章从数字签名底层原理出发,逐步深入到Authenticode签名机制与交叉证书签名的实际应用,帮助开发者建立完整的驱动签名知识体系。
2.1 数字签名原理
数字签名并非简单的加密,而是基于公钥基础设施(PKI)的完整性验证与身份认证机制。驱动签名主要解决三个核心问题:
- 身份认证:确认驱动发布者的真实身份
- 完整性校验:确保驱动文件未被篡改
- 不可否认性:发布者无法否认其签名行为
数字签名的核心流程包含签名生成与签名验证两个阶段,其工作原理如下图所示:
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
2.2.3 Authenticode签名验证流程
Windows系统在加载驱动时,会执行以下Authenticode验证步骤:
- 解析PE文件:定位Certificate Table,提取PKCS #7签名数据
- 构建证书链:从签名者证书回溯到受信任的根证书颁发机构(CA)
- 验证证书有效性:检查证书是否过期、是否被吊销(CRL/OCSP)
- 计算文件哈希:对PE文件内容(排除Certificate Table)计算SHA256哈希
- 比对哈希值:将计算出的哈希值与签名中的哈希值进行比对
- 检查时间戳:验证时间戳签名是否有效,确保签名在证书有效期内完成
2.3 交叉证书签名
交叉证书签名是解决证书链信任问题的关键技术。当驱动签名证书由非微软根CA颁发时,需要通过交叉证书将签名证书链桥接到微软根CA,以确保在Windows系统上被信任。
2.3.1 为什么需要交叉证书
Windows系统预置了受信任的根证书列表。如果驱动签名证书的根CA不在该列表中,系统将无法验证签名链,导致驱动加载失败。交叉证书的作用如下:
- 桥接信任:将第三方CA的根证书链接到微软根CA
- 兼容旧系统:Windows 7/8等系统可能未包含较新的CA根证书
- 满足EV要求:扩展验证(EV)代码签名证书需要交叉证书支持
2.3.2 交叉证书签名流程
交叉证书签名的完整流程如下图所示:
2.3.3 交叉证书获取与使用
交叉证书通常由CA机构提供,或从微软官方下载。以下是使用交叉证书进行签名的完整步骤:
- 获取交叉证书:从CA机构或微软下载对应的交叉证书文件(.cer格式)
- 安装交叉证书:将交叉证书导入到本地计算机的“受信任的根证书颁发机构”存储区
- 执行签名:使用SignTool的
/ac参数指定交叉证书文件 - 验证签名:使用
signtool verify /v /kp命令验证签名链完整性
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检查证书存储区,确保所有中间证书和交叉证书已正确安装。