开源之夏04:密钥管理与密码学安全设计

在密码设备开发中,密钥管理是绝对的核心。这周通过 SDF 接口的深入学习和代码实现,理清了困扰已久的几个基础问题。

密码学四要素与工具选择

密码学第一课说:这门课程主要阐述如何利用密码技术实现信息的机密性、完整性、可鉴别性和抗抵赖性。但为什么有了数字签名还要消息鉴别?为什么还要身份鉴别?这些技术背后的联系是什么?

核心推理链是这样的:

  1. 数学上证明:只要密钥不泄露,加密的内容就是安全的。
  2. 因此推论:假设密钥完成分发,不考虑重放,使用密钥加密保护信息传递,保证密钥安全,各种业务场景就都是安全的。
  3. 于是:需要保护密钥,让它在每次用完后都能被妥善保管,不丢失泄露。

不同密码工具解决不同层面的问题:

工具 完整性 身份鉴别 不可否认性 说明
MAC/HMAC ✔ ✘ ✘ 只能证明”有人拥有同一对称密钥”
数字签名 ✔ ✔ ✔ 签名用私钥,验签用公钥/证书
挑战-响应协议 间接 ✔ 间接 解决”此刻对端是不是声称的实体”

完整的信任链

  1. 密钥本身:只是一串随机比特,本身没有任何”意义”。
  2. 谁有权用它(最小授权/访问控制):通过 PIN、口令、HSM 角色把”实体→密钥使用权”绑定,但不透露密钥。
  3. 消息鉴别(MAC/HMAC):解决”消息在传输途中是否被篡改”。对称密钥本身不表明”谁”产生的——拿到密钥就能伪造 MAC。
  4. 数字签名(SM2/RSA):私钥永远留在设备内,公钥可以公开。验证链条的最后一环:私钥只负责”计算签名”,身份由”公钥证书”绑定,”谁有权用私钥”由 HSM 的访问控制决定。形成”实体 / 密钥使用权 / 签名结果”三层分离。
  5. 身份鉴别(挑战-响应、TLS 握手):组合使用 MAC 或数字签名,现场证明”此刻使用这把私钥的人就是那个被认证的实体”。

统一的指导思想:最小权限原则(Principle of Least Privilege)+ 分层信任模型(Layered Trust)——把敏感资产(密钥、消息、身份)从逻辑与物理上逐层最小化暴露,任何一层泄露都不足以破坏整体信任。

SDF 密钥管理三维度

SDF 规范用不同的接口组合覆盖密钥管理的全部交叉点。任何一把密钥都可以被描述为:

(持久/会话/临时)×(内部/外部)×(签名/加密/对称)

维度一:生命周期

把密钥按时间维度切成三档,对应密码设备在安全、性能、合规三个维度上无法同时满足的”不可能三角”:

类型 存储 安全 性能 典型场景
持久密钥 NVRAM,掉电不丢 最高(私钥永不出芯片) 访问慢 根密钥、CA 私钥
会话密钥 易失 RAM,关闭即销毁 中等(泄露只影响一次会话) 平衡 单次通信加密
临时密钥 瞬时生成、用完即毁 可接受的一次性风险 极限 海量并发、零持久化

会话密钥负责”会话内不泄密”,持久密钥负责”跨会话还能认人”。两者缺一不可。

维度二:使用权限

  • 内部密钥:私钥永不出设备,只能做内部运算(签名、解密)
  • 外部密钥:私钥(或会话密钥明文)可以导出到主机内存

维度三:功能用途

  • 签名密钥对:ExportSignPublicKey / GenerateSignKeyPair
  • 加密密钥对:ExportEncPublicKey / GenerateEncKeyPair
  • 对称会话密钥:GenerateKey、ImportKeyWithKEK 等

密钥封装与 KEK 体系

SDF 标准的推荐业务流程是”会话密钥+密钥封装”:

数据不直接用非对称私钥解密,而是用对称会话密钥加密/解密,非对称密钥只用于加密/解密会话密钥。

典型流程:

  1. 发送方生成随机对称会话密钥(如 SM4),用接收方公钥加密该会话密钥得到”密钥密文”
  2. 用会话密钥加密数据得到”数据密文”
  3. 发送”密钥密文+数据密文”
  4. 接收方用自己的私钥解封会话密钥,再用会话密钥解密数据

KEK vs IPK/EPK/ISK

这几个概念容易混淆,本质上是不同场景的密钥封装方案:

机制 类型 适用场景 性能
EPK/ISK 非对称(公钥加密) 跨系统/跨设备安全传递 慢,安全高
IPK 非对称 同设备内不同进程/模块间隔离 慢,安全高
KEK 对称 设备内部或同域密钥封装、备份、迁移 快

KEK(密钥加密密钥)是设备内部生成并长期安全存储的对称密钥,专门用于加密/解密会话密钥。它的生命周期长,只有设备内部能直接使用,外部应用只能通过索引引用。KEK 不是替代 IPK/EPK,而是为设备内部高效安全的密钥管理提供补充——快的那条路。

KEK 走对称加密路线,速度快适合高频操作;IPK/EPK 走非对称路线,安全性高但速度慢适合跨域场景。两者互补构成完整的密钥管理体系。

设备→会话→密钥 三级句柄架构

这是密码硬件领域经过二十多年迭代后最通用的架构:

1
2
设备(Device) → 会话(Session) → 密钥(Key)
全局 登录态内 最小操作单元

每一层解决不同的矛盾:

层级 解决什么 生命周期
设备 全局配额、权限隔离 进程级
会话 并发隔离、认证状态、对象列表 登录态
密钥 受保护的密钥对象,仅暴露整数句柄 会话或持久

为什么要这样设计?因为在单块芯片上需要同时满足:多用户并发、密钥最小暴露、资源可计量、运维可管理——单靠任何一层都做不到。

会话句柄退出或关闭即可零成本”擦除”临时密钥,减少应用层忘记清内存的安全风险。密钥句柄只暴露 32/64 位整数而非密钥明文,即使句柄泄露也无法直接获取密钥材料。

SM2 签名与密钥协商

Z 值的计算与作用

SM2 签名算法中的 Z 值是一个”用户身份绑定杂凑值”:

1
Z值 = SM3(用户ID || 椭圆曲线参数 a,b,G,n,p || 公钥 x,y)

作用:防止公钥替换攻击。攻击者如果替换公钥并伪造签名,由于 Z 值绑定了用户身份和公钥,验签时计算出不同的 Z 值会导致验证失败。

SDF 标准规定:调用 SDF_HashInit 时传入 ECC 公钥和用户 ID,设备自动完成 Z 值计算。随后 SDF_HashUpdate 拼接 Z||M(原始消息),SDF_HashFinal 输出 “SM2 预处理+SM3”后的摘要。

密钥协商中的双重密钥

SM2 密钥协商同时使用主公钥(长期密钥) 和临时公钥,二者缺一不可:

  • 主公钥:经 CA 认证、长期绑定用户身份,防止中间人伪造身份。
  • 临时公钥:每次会话动态生成,提供前向安全性(Forward Secrecy)——即使长期密钥泄露,历史会话密钥也不会被恢复。

只用主密钥:有身份认证但无前向安全。只用临时密钥:有前向安全但无法认证身份。两者结合才是现代密钥协商的标准做法。

柔性数组

SDF 标准的 ECCCipher 结构中密文字段 C[] 使用了柔性数组(Flexible Array Member):

1
2
3
4
5
6
7
8
typedef struct ECCCipher_st {
unsigned char x[ECCref_MAX_LEN];
unsigned char y[ECCref_MAX_LEN];
unsigned char M[32];
unsigned int L;
unsigned char C[1]; // C89 兼容写法
unsigned char C_[254]; // 实际扩展空间
} ECCCipher;

C99 正式引入 C[](未指定长度的数组),C89/C90 时代常用 C[1] 占位。原理:结构体大小只包含 C[1] 的 1 字节,但可以通过 malloc 分配更大空间,把多余部分当作变长数组使用。广泛用于协议、密码学等需要变长数据的场景。

硬件攻击面:芯片安全 ≠ 系统安全

SDF 的”芯片”很安全,但芯片到 CPU 这条 PCIe 总线以及宿主机系统仍是可攻击面。”没人会攻击密码卡”是一个危险的错觉:

攻击者 典型目标 动机
国家级 APT 政府/军工/金融根证书 长期潜伏、情报窃取
犯罪集团 POS 机、加密 U-Key 直接套现、银行卡复制
云厂商内部人 大客户加密卡 横向提权、盗窃 API 密钥
学术/白帽 发表论文、CVE 经费、声誉

攻击门槛并不高:PCIe 协议分析仪只需 $3000,开源工具链(ChipWhisperer、Glasgow)让本科生 1-2 周即可复现功耗攻击。机密计算正是为了解决这个问题——用 CPU 自身 TEE(Trusted Execution Environment)消除芯片到 CPU 总线的可攻击面。


开源之夏04:密钥管理与密码学安全设计
https://47.108.189.123/2025/08/25/开源之夏/04-密钥管理与密码学安全设计/
Author
Dong
Posted on
August 25, 2025
Licensed under