3、密码学基础(下):对称加密与非对称加密、密钥管理、硬件安全模块(HSM/TPM)的角色
好,我们接着往下聊。上一节我们把哈希、MAC、数字签名这些基础工具过了一遍。这一节,咱们得啃硬骨头了——对称加密、非对称加密,还有密钥管理。说实话,这部分是安全启动的「心脏」。你算法选得再好,密钥管得一塌糊涂,那整个信任链就是纸糊的。
3.1 对称加密:又快又稳的「老黄牛」
对称加密,说白了就是加密和解密用同一把钥匙。你想想看,就像你家里的大门,用一把钥匙锁上,也用同一把钥匙打开。效率极高,特别适合处理大量数据。
我在项目中遇到过最典型的场景,就是固件镜像的加密存储。芯片启动时,需要从Flash里把固件读出来,这时候如果用非对称加密去解密整个镜像,那速度慢得会让你怀疑人生。所以实际做法是:用对称加密(比如AES)把固件 bulk 加密,启动时用硬件加速器秒解。
3.1.1 主流算法选型
| 算法 | 密钥长度 | 典型应用场景 | 我的建议 |
|---|---|---|---|
| AES | 128 / 256 bit | 固件加密、通信加密 | 首选,硬件支持最广 |
| SM4 | 128 bit | 国密合规场景 | 国内项目必选 |
| ChaCha20 | 256 bit | 无AES硬件加速的MCU | 软件实现效率高 |
3.1.2 工作模式的选择陷阱
嗯,这里要注意。AES算法本身只是「块加密」,怎么处理多块数据,这就是模式的事了。我见过太多人栽在这个坑里。
- ECB模式: 千万别用。同样的明文块会生成同样的密文块,这在固件加密里是致命的——攻击者能看出固件的结构。
- CBC模式: 需要IV(初始化向量),但IV不能重复。我曾经调试过一个bug,就是因为每次启动IV都固定,导致攻击者可以重放攻击。
- GCM模式: 我个人最推荐。它同时提供加密和认证,一次搞定。在安全启动里,用GCM模式加密固件,还能顺便校验完整性。
// 伪代码示例:使用AES-GCM加密固件块
// 注意:密钥从HSM中获取,IV使用硬件随机数生成器
aes_gcm_ctx_t ctx;
uint8_t key[16]; // 从HSM安全导出
uint8_t iv[12]; // 硬件TRNG生成,每次启动不同
aes_gcm_init(&ctx, key, iv);
aes_gcm_encrypt(&ctx, plaintext, plaintext_len, ciphertext);
aes_gcm_final(&ctx, tag, 16); // tag用于校验
// 将ciphertext + tag写入Flash
flash_write(offset, ciphertext, plaintext_len);
flash_write(offset + plaintext_len, tag, 16);
3.2 非对称加密:安全但慢的「保险柜」
非对称加密,就是公钥和私钥成对出现。公钥可以公开,私钥必须保密。你想想看,这就像是一个信箱,任何人都可以把信投进去(用公钥加密),但只有你有钥匙能打开(用私钥解密)。
在安全启动里,非对称加密主要用来做两件事:签名验证和密钥交换。说白了,它不直接加密大量数据,而是用来保护那个「加密大量数据的对称密钥」。
3.2.1 RSA vs ECC:老将与新秀
| 特性 | RSA | ECC(如ECDSA、Ed25519) |
|---|---|---|
| 密钥长度 | 2048 / 4096 bit | 256 / 384 bit |
| 签名速度 | 慢(私钥操作) | 快 |
| 验签速度 | 快(公钥操作) | 较快 |
| 硬件资源 | 需要大数运算单元 | 资源友好 |
3.2.2 混合加密:取长补短
实际工程里,我们很少只用一种加密。最常见的模式是「混合加密」:
- 用非对称加密(如RSA)加密一个临时生成的对称密钥(会话密钥)。
- 用这个对称密钥(如AES-GCM)加密实际数据。
- 传输时,把加密后的会话密钥和加密数据一起发过去。
为什么这么做?因为非对称加密太慢了。你想想看,一个固件可能有几十兆,用RSA逐块加密,那得等到天荒地老。而用AES加密,硬件加速器一秒钟能处理几百兆。所以,非对称加密只保护「钥匙」,对称加密保护「箱子」。
3.3 密钥管理:安全启动的「命门」
说实话,密钥管理是整个安全启动里最难的部分。算法可以抄开源,代码可以review,但密钥一旦泄露,一切归零。我见过太多项目,算法选得漂漂亮亮,结果密钥硬编码在代码里,或者烧录时被调试器读出来了。
3.3.1 密钥生命周期管理
一个密钥从生到死,每个阶段都要管好:
- 生成: 必须在安全环境中生成(如HSM内部),不能由软件随机数生成。我曾经见过有人用rand()生成密钥,那玩意儿 predictability 太强了。
- 存储: 私钥永远不能以明文形式出现在Flash或文件系统里。必须用硬件安全模块保护,或者至少用PUF(物理不可克隆函数)派生。
- 使用: 密钥只在硬件安全模块内部使用,软件只能请求「用密钥做签名/解密」,不能拿到密钥本身。
- 销毁: 密钥废弃后,要从所有存储介质中物理擦除。Flash的擦除要注意,有些Flash有「幽灵页」,擦不干净。
3.3.2 密钥层级结构
我个人习惯用三层密钥体系:
| 层级 | 名称 | 存储位置 | 用途 |
|---|---|---|---|
| L1 | 根密钥(Root Key) | 芯片eFuse或OTP | 保护下级密钥,不可读取 |
| L2 | 设备密钥(Device Key) | HSM内部安全存储 | 签名验证、会话密钥派生 |
| L3 | 会话密钥(Session Key) | 运行时内存(加密态) | 单次通信或启动会话 |
3.4 硬件安全模块(HSM/TPM):信任的「锚点」
你想想看,如果密钥存在Flash里,攻击者用探针就能读出来。那怎么办?答案就是硬件安全模块。它本质上是一个独立的「安全岛」,有自己的CPU、存储和加密引擎,主CPU只能通过特定接口跟它通信。
3.4.1 HSM vs TPM:有什么区别?
- HSM(硬件安全模块): 通常是板级或芯片级的安全协处理器。性能强,可以做大量加解密操作。用在汽车、服务器等高端场景。
- TPM(可信平台模块): 更轻量,通常集成在PC或IoT芯片里。主要做密钥存储、平台完整性度量(PCR寄存器)。
在实际项目中,我建议这样选:如果你的芯片有内置HSM(比如NXP的i.MX系列、ST的STM32H5),直接用HSM。如果只有TPM(比如Infineon的SLB9670),那就用TPM做信任根,配合主CPU做上层逻辑。
3.4.2 HSM的核心能力
- 安全密钥存储: 密钥生成在HSM内部,私钥永远不离开HSM。
- 硬件加速加解密: AES、RSA、ECC都有专用硬件,性能远超软件。
- 真随机数生成(TRNG): 基于物理噪声,不是伪随机。
- 安全启动支持: HSM可以验证第一级bootloader的签名,然后逐级验证。
- 防篡改检测: 检测到物理攻击(如探针、电压毛刺)时,自动销毁密钥。
3.4.3 实际使用示例:TPM做平台完整性度量
// 伪代码:使用TPM PCR寄存器度量启动过程
// 每个阶段将代码哈希扩展到PCR
tpm_ctx_t tpm;
uint8_t pcr_index = 0; // PCR0用于bootloader度量
// 阶段1:度量bootloader本身
tpm_pcr_extend(&tpm, pcr_index, bootloader_hash, 32);
// 阶段2:度量OS内核
tpm_pcr_extend(&tpm, pcr_index, kernel_hash, 32);
// 阶段3:度量关键配置
tpm_pcr_extend(&tpm, pcr_index, config_hash, 32);
// 最终PCR0的值 = SHA256(boot_hash || kernel_hash || config_hash)
// 远程验证方可以比对PCR0的值,判断平台是否被篡改
嗯,这里要注意。TPM的PCR寄存器是「只能扩展,不能重置」的(除了平台复位)。这意味着一旦某个环节被篡改,最终的PCR值就会不同,远程验证方就能发现异常。这就是信任链的「链式度量」思想。
3.5 小结:把理论落到工程里
这一节内容不少,我帮你理一下核心脉络:
- 对称加密 负责「快」,加密大量数据。选AES-GCM,别碰ECB。
- 非对称加密 负责「安全」,保护密钥和签名。ECC比RSA更适合嵌入式。
- 密钥管理 是命门,用层级结构,私钥永远不出HSM。
- HSM/TPM 是信任锚点,所有安全操作都基于它。
说实话,这些理论听起来可能有点抽象。但等你真正做项目时,就会发现每一个决策都关乎产品的生死。下一节,我们会把这些密码学工具串起来,构建完整的信任链。到时候,你会看到它们是如何协同工作的。