2. UEFI基础回顾
安全启动这套机制,说白了就是一套「信任链」——从硬件到操作系统,每一环都要验证下一环的签名。而支撑这条链的,就是四个核心组件:PK(平台密钥)、KEK(密钥交换密钥)、db(签名数据库)、dbx(吊销签名数据库)。
我在项目中见过不少工程师把这四个东西搞混,甚至有人把 PK 和 KEK 当成一回事。嗯,今天我们就把它彻底理清楚。
2.1 四个组件的关系与职责
先看一张整体关系图,你就能明白它们各自的位置。
从图上你能看到:PK 是信任的根,它授权 KEK;KEK 负责管理 db 和 dbx 的更新;而 db 和 dbx 共同决定哪些程序能运行。这个层级关系一旦建立,就不能随意打破——除非你拥有 PK 的私钥。
2.2 PK(平台密钥)——信任的起点
PK 是整个安全启动体系的「最高权限」。它由平台所有者(通常是你自己或 OEM)持有,私钥必须严格保护。
我个人习惯把 PK 比作「保险柜的总钥匙」——丢了它,你就再也无法修改安全启动的任何配置。
| 属性 | 说明 |
|---|---|
| 存储位置 | UEFI 非易失性变量(PK) |
| 用途 | 验证 KEK 更新的签名 |
| 数量限制 | 通常只能有一个 PK(部分实现允许多个) |
| 删除条件 | 必须用当前 PK 私钥签名删除请求 |
2.3 KEK(密钥交换密钥)——授权的中间层
KEK 的作用是「授权」。它被 PK 签名后,就获得了更新 db 和 dbx 的权限。你可以有多个 KEK,每个 KEK 对应不同的操作系统或管理工具。
举个例子:你安装了 Windows,Windows 的签名证书会被加入 KEK。这样 Windows 更新程序就能合法地修改 db 和 dbx。如果你自己写了一个工具来管理安全启动,也需要把工具的证书加入 KEK。
2.4 db(签名数据库)——白名单
db 里存放的是「允许执行」的签名或哈希。UEFI 固件在启动每个程序(比如 bootloader、Option ROM、驱动)时,都会检查它的签名是否在 db 中。如果在,就放行;如果不在,就拒绝启动。
db 可以包含三种类型的数据:
- X509 证书——最常用,验证签名链
- SHA-256 哈希——直接匹配文件的哈希值
- SHA-1 哈希——旧版兼容,不推荐
我记得有一次调试一个第三方网卡的 Option ROM,它死活启动不了。查了半天,发现它的签名证书没在 db 里。手动添加后,问题解决。说白了,db 就是安全启动的「门禁系统」——没在名单上的,一律不让进。
2.5 dbx(吊销签名数据库)——黑名单
dbx 和 db 正好相反:它存放的是「禁止执行」的签名或哈希。如果一个程序的签名在 dbx 中,即使它也在 db 中,仍然会被拒绝启动。dbx 的优先级高于 db。
你想想看,为什么需要 dbx?因为总有证书会泄露、总有旧版本有漏洞。比如某个 bootloader 被发现存在安全漏洞,OEM 就会把它的签名或哈希加入 dbx,这样即使攻击者拿着合法的签名文件,也无法启动那个有漏洞的版本。
| 对比项 | db | dbx |
|---|---|---|
| 作用 | 允许执行 | 禁止执行 |
| 优先级 | 低(被 dbx 覆盖) | 高(覆盖 db) |
| 更新频率 | 较高(添加新硬件/系统) | 较低(仅安全事件时更新) |
| 典型内容 | OEM 证书、OS 证书 | 泄露证书、有漏洞的 bootloader 哈希 |
2.6 四个组件的交互流程
理解了每个组件的作用,我们来看看它们在实际启动中是怎么配合的。
- 固件启动:读取 PK,确认安全启动是否启用。如果 PK 为空,进入设置模式。
- 验证 KEK:用 PK 的公钥验证 KEK 的签名。如果 KEK 被篡改,启动失败。
- 验证启动项:用 KEK 授权的 db 和 dbx 来验证每个启动项的签名。
- 检查 dbx:先看启动项的签名是否在 dbx 中。如果在,直接拒绝。
- 检查 db:如果不在 dbx 中,再看是否在 db 中。如果在,允许启动;如果不在,拒绝。
核心原则:信任链从 PK 开始,逐级向下。每一级只能验证下一级的签名,不能越级。PK 不能直接修改 db,KEK 不能直接修改 PK——这就是安全启动的「最小权限」设计思想。
2.7 实战中的常见问题
我在支持客户时,遇到最多的问题集中在以下几点:
- PK 丢失后怎么办?——如果 PK 私钥丢失,唯一的办法是清空 NVRAM(通常通过主板跳线或固件设置),这会同时清空所有安全启动配置。嗯,代价很大。
- KEK 和 db 混淆——有人把操作系统证书直接加到 KEK,其实应该加到 db。KEK 只负责「授权管理」,不负责「授权执行」。
- dbx 更新失败——dbx 更新需要 KEK 签名。如果 KEK 证书过期或私钥丢失,就无法更新 dbx。我曾经遇到过客户因为 KEK 证书过期,导致无法吊销一个已知有漏洞的 bootloader——最后只能通过固件升级来重置整个安全启动配置。