2. 安全启动核心组件:PK、KEK、db、dbx

安全启动这套机制,说白了就是一套「信任链」——从硬件到操作系统,每一环都要验证下一环的签名。而支撑这条链的,就是四个核心组件:PK(平台密钥)、KEK(密钥交换密钥)、db(签名数据库)、dbx(吊销签名数据库)。

我在项目中见过不少工程师把这四个东西搞混,甚至有人把 PK 和 KEK 当成一回事。嗯,今天我们就把它彻底理清楚。

2.1 四个组件的关系与职责

先看一张整体关系图,你就能明白它们各自的位置。

安全启动核心组件关系图 安全启动核心组件关系图 PK(平台密钥) 信任根,由平台所有者持有 KEK(密钥交换密钥) 管理 db/dbx 更新的授权 db(签名数据库) 允许执行的签名/哈希 dbx(吊销数据库) 禁止执行的签名/哈希 信任链传递 PK 签名 KEK → KEK 签名 db/dbx 更新 → db 验证启动项签名 dbx 中的签名/哈希永远被拒绝,优先级高于 db

从图上你能看到:PK 是信任的根,它授权 KEK;KEK 负责管理 db 和 dbx 的更新;而 db 和 dbx 共同决定哪些程序能运行。这个层级关系一旦建立,就不能随意打破——除非你拥有 PK 的私钥。

2.2 PK(平台密钥)——信任的起点

PK 是整个安全启动体系的「最高权限」。它由平台所有者(通常是你自己或 OEM)持有,私钥必须严格保护。

我个人习惯把 PK 比作「保险柜的总钥匙」——丢了它,你就再也无法修改安全启动的任何配置。

属性 说明
存储位置 UEFI 非易失性变量(PK)
用途 验证 KEK 更新的签名
数量限制 通常只能有一个 PK(部分实现允许多个)
删除条件 必须用当前 PK 私钥签名删除请求
⚠️ 重要提醒:PK 一旦被清空(设为空变量),安全启动会自动进入「设置模式」(Setup Mode)。此时任何人都可以写入新的 PK。我在项目中遇到过客户误操作导致 PK 丢失,整批设备需要返厂重刷固件——所以操作 PK 前,务必确认你备份了私钥。

2.3 KEK(密钥交换密钥)——授权的中间层

KEK 的作用是「授权」。它被 PK 签名后,就获得了更新 db 和 dbx 的权限。你可以有多个 KEK,每个 KEK 对应不同的操作系统或管理工具。

举个例子:你安装了 Windows,Windows 的签名证书会被加入 KEK。这样 Windows 更新程序就能合法地修改 db 和 dbx。如果你自己写了一个工具来管理安全启动,也需要把工具的证书加入 KEK。

💡 实战建议:我建议至少保留两个 KEK——一个用于操作系统,一个用于你自己的管理工具。这样即使某个 KEK 的私钥泄露,你还能用另一个 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 四个组件的交互流程

理解了每个组件的作用,我们来看看它们在实际启动中是怎么配合的。

  1. 固件启动:读取 PK,确认安全启动是否启用。如果 PK 为空,进入设置模式。
  2. 验证 KEK:用 PK 的公钥验证 KEK 的签名。如果 KEK 被篡改,启动失败。
  3. 验证启动项:用 KEK 授权的 db 和 dbx 来验证每个启动项的签名。
  4. 检查 dbx:先看启动项的签名是否在 dbx 中。如果在,直接拒绝。
  5. 检查 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——最后只能通过固件升级来重置整个安全启动配置。
🔧 我的建议:在生产环境中,一定要把 PK 和 KEK 的私钥离线存储,最好使用硬件安全模块(HSM)。db 和 dbx 的更新策略要提前规划好——比如哪些证书需要预置、哪些场景需要紧急更新 dbx。别等到出事了才手忙脚乱。