4、硬件唯一密钥(HUK):HUK的生成、存储、与派生机制

好,咱们今天聊点硬核的——硬件唯一密钥,圈内人通常叫它 HUK。这玩意儿是什么?说白了,它就是一颗芯片出生时就带在身上的“身份证”,而且是绝密级别的。你想想看,一台平板电脑,从你按下电源键到进入桌面,中间要经历多少道安全校验?HUK 就是这些校验的根,是所有信任的起点。

我做过好几款平板的量产项目,每次跟客户聊安全方案,第一件事就是问:“你们的 HUK 怎么管?” 很多人觉得这玩意儿不就是写个随机数进去嘛。嗯,没那么简单。今天我就把 HUK 的生成、存储和派生机制,掰开了揉碎了讲给你听。

4.1 HUK 是怎么“生”出来的?

HUK 的生成,讲究的是“不可预测”和“唯一性”。你不能用软件去算一个出来,因为软件跑在 CPU 上,容易被侧信道攻击给扒光。真正的做法,是在芯片制造阶段就搞定。

我个人习惯把 HUK 的生成方式分成三类,你对照着看:

生成方式 原理 优点 缺点
物理不可克隆函数(PUF) 利用芯片制造时的工艺偏差,比如 SRAM 上电时的初始值 不可克隆,芯片物理唯一 受温度、电压影响,需要纠错
熔丝/反熔丝 在芯片内部烧断或连接特定熔丝,形成二进制编码 稳定、一次性写入 不可更改,一旦烧错就报废
OTP(一次性可编程)存储器 在芯片测试阶段写入随机数 灵活,可批量编程 需要安全写入环境

我在项目中遇到过用 SRAM PUF 的方案。当时选型时,供应商吹得天花乱坠,说这玩意儿绝对安全。结果量产时发现,同一批芯片在不同温度下读出的 HUK 居然有几位翻转了。嗯,后来我们不得不加了一套纠错电路,才把问题搞定。所以啊,PUF 虽好,但工程落地时一定要考虑环境鲁棒性。

我的建议: 如果你的产品对成本敏感,直接用 OTP 写入随机数是最稳妥的。PUF 适合那些对防物理拆解要求极高的场景,比如金融支付终端。

4.2 HUK 存哪儿?怎么存才安全?

HUK 生成之后,就得找个地方藏起来。你想想看,如果 HUK 被存在 Flash 里,攻击者用探针一戳就能读出来,那前面所有的努力都白费了。所以,HUK 必须存储在芯片内部的“安全飞地”里。

常见的存储位置有:

  • 专用安全寄存器:位于 SoC 内部,只有安全子系统能访问。
  • eFuse 阵列:一次性编程,物理上不可擦除。
  • 安全 NVRAM:带访问控制,但需要电池备份。

这里有个关键点:HUK 永远不应该被软件直接读取。你想想看,如果应用层能调用一个 API 把 HUK 读出来,那跟把钥匙挂在门上有什么区别?正确的做法是,HUK 只暴露给硬件安全模块(HSM)或安全协处理器,软件只能请求“用 HUK 做点什么”,而不能拿到 HUK 本身。

我曾经踩过的坑: 有一款平板,设计时把 HUK 放在了系统控制器的寄存器里,结果被一个调试接口给暴露出来了。攻击者通过 JTAG 直接 dump 了整个寄存器空间,HUK 就裸奔了。从那以后,我要求所有 HUK 相关的存储必须经过“总线防火墙”隔离。

4.3 HUK 的派生机制:一棵密钥树

HUK 本身是根密钥,你不能直接用 HUK 去加密用户数据。为什么?因为一旦 HUK 泄露,所有派生出来的密钥都会失效。所以,我们需要一套派生机制,从 HUK 生成各种用途的子密钥。

我习惯把这套机制叫做“密钥派生树”。它的核心思想是:用 HUK 作为种子,结合不同的上下文信息,通过单向函数生成不同的子密钥

举个例子,假设我们要为磁盘加密生成一个密钥:

// 伪代码示例:HUK 派生磁盘加密密钥
// HUK: 硬件唯一密钥,128位
// context: 上下文信息,比如 "disk_encryption_key_v1"
// salt: 随机盐值,存储在非安全区域

derived_key = KDF(HUK, context, salt, key_length=256)

// KDF 通常使用 HMAC-SHA256 或 AES-CMAC
// 输出:256位的磁盘加密密钥

你看,这里 HUK 并没有直接暴露,而是通过 KDF(密钥派生函数)生成了一个新密钥。即使攻击者拿到了这个派生密钥,他也无法反推出 HUK。这就是“一次一密”的思想。

常见的派生场景包括:

  • 磁盘加密密钥:用 HUK + 分区 UUID 派生。
  • 设备认证密钥:用 HUK + 设备序列号派生。
  • 安全启动校验密钥:用 HUK + 固件版本号派生。

我个人习惯在派生时加入一个“版本号”字段。这样,当算法需要升级时,只需要改变版本号,就能生成一套全新的密钥,而 HUK 本身纹丝不动。这招在 OTA 升级时特别有用。

4.4 实战中的避坑指南

讲了这么多理论,最后给你几个实战中的建议。这些都是我拿真金白银换来的教训:

  1. 别把 HUK 当万能钥匙。HUK 只负责派生,不负责加解密。所有加解密操作都应该在安全硬件内部完成。
  2. 注意派生函数的性能。有些 KDF 算法(比如 PBKDF2)计算量很大,在嵌入式设备上可能跑不动。我建议用 HMAC-SHA256 或 AES-CMAC,速度快且安全。
  3. 留好熔丝回读保护。eFuse 烧录后,一定要把回读路径物理切断。否则攻击者可以通过扫描电镜读出熔丝状态。
  4. 考虑 HUK 的备份机制。如果 HUK 丢失,设备就变砖了。我见过一个方案,把 HUK 用门限秘密共享算法拆成三份,分别存在三个不同的安全区域。这样即使坏掉一个,也能恢复。

核心总结:

  • HUK 是硬件信任的根,必须在芯片制造阶段生成。
  • HUK 存储在安全飞地中,软件不可直接读取。
  • 通过 KDF 派生子密钥,实现“一次一密”。
  • 工程落地时,务必考虑温度稳定性、性能开销和备份机制。

好了,HUK 这块就讲这么多。下一章咱们聊聊安全启动链,看看 HUK 是怎么在系统启动时发挥作用的。到时候我会给你展示一个完整的启动校验流程,保证让你大开眼界。