开源之夏-13

这次被上强度了~
现在三个任务

  • 完成SDF所有接口的加载与函数绑定
  • 完成TSAPI对SDF的包装,要求足够的鲁棒性,符合工程规范
  • 已完成模块可以直接拿出去单开项目测试。
    (不仅要求我有想法,还要我肯定地提出自己的解决方案,并符合工程规范……)
    (上周老师还把我当学生,这周要真干了,这周过完就20岁啦!)
    (而且还会提问,对于各种接口的工程设置原因,算法细节,业务流程,必须清楚,而且是非常清楚)
    (初学者的借口不太好用了,啊啊啊啊啊啊啊)

在 SDF(GMT 0018-2023)的语义里,除了

  • 静态内置密钥(Export/Use)
  • 动态即时密钥(Generate/Create)

之外,还有三条“轴”把密钥生命周期和用途拆得更细。把这几条轴交叉起来,就能解释为什么规范里会出现那么多看似重复、实则互补的接口。

  1. 密钥的“持久化级别”

    • 持久密钥(Persistent/Static)——掉电不丢,索引号固定,由管理员提前注入或出厂自带。
    • 会话密钥(Session/Ephemeral)——只在一次会话或一次调用内有效,设备断电即消失,典型如 SDF_GenerateKeyWithIPK/EPK 产生的对称密钥。
    • 临时密钥(Temporary/One-shot)——介于两者之间,比如用 SDF_GenerateKeyPair_RSA 当场生成、用完后立即销毁或导出私钥到主机,设备里不留痕迹。
  2. 密钥的“使用权限”
    内部密钥(Internal Only)——私钥永不出设备,只能做内部运算(签名、解密)。
    外部密钥(External)——私钥(或会话密钥明文)可以导出到主机内存,由应用自行保管。
    这在接口命名上体现为:

    • ImportKeyPair / ImportKeyWithISK(私钥从外部进设备)
    • ExportKeyPair / ExportKeyWithISK(私钥从设备出到外部)
    • GenerateKeyWithIPK(内部公钥加密) vs. GenerateKeyWithEPK(外部公钥加密)
  3. 密钥的“功能用途”
    签名密钥对(SignKey)——对应 ExportSignPublicKey_RSA / GenerateSignKeyPair_RSA。
    加密密钥对(EncKey)——对应 ExportEncPublicKey_RSA / GenerateEncKeyPair_RSA。
    对称密钥(SessionKey)——对应 GenerateKeyWithIPK_RSA / GenerateKeyWithEPK_RSA / GenerateRandomKey 等。
    用途不同,密钥属性(KeyUsage、KeyIndex)和访问控制策略也不同;SDF 通过不同接口把这三者显式区分。

把三条轴叠加起来,任何一把密钥都可以被描述成:

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

而 SDF 规范正是用不同的接口组合来覆盖这些交叉点。因此除了“静态内置”和“动态即时”两大模式外,真正“还有什么”可以用一句话总结为:

还有“生命周期(持久/会话/临时)”、“导出权限(内部/外部)”、“功能用途(签名/加密/对称)”这三条维度,共同构成了 SDF 完整而细粒度的密钥管理体系。

把密钥按“持久 / 会话 / 临时”三档来划分,并不是为了“多几个名词”,而是直接对应密码设备在安全、性能、合规三个维度上无法同时满足的“不可能三角”。只有把时间维度切开,才能在每一档里各取所需、互不拖累。

  1. 安全:私钥永不出设备、最小暴露面
    • 持久密钥:一次性注入后私钥锁死在安全芯片里,连管理员都拿不出来。这样即使主机被完全攻陷,也偷不到根密钥。
    • 会话/临时密钥:反正用完就扔,就算泄露也只是“一次性会话”的损失,不会危及长期信任根。

  2. 性能与资源:芯片存储和算力都很贵
    • 持久密钥:NVRAM 有限,不可能给每个应用、每次会话都留一把长期 RSA 密钥。
    • 会话/临时密钥:生成后只放在易失 RAM,甚至直接输出到主机,不占 NVRAM;用完即毁,芯片可以“无状态”地服务海量并发。
    • 临时密钥还能让主机在本地做加解密,减轻芯片负载,提高吞吐。

  3. 合规与审计:生命周期可追踪
    • 持久密钥:必须遵循严格的密钥注入、备份、销毁流程,满足国密、等保、FIPS 140 等审计要求。
    • 会话/临时密钥:生命周期短,日志只需记录“生成-销毁”两笔,无需长期密钥托管,审计简单。
    • 例如,PCI-DSS 明确禁止把持卡人数据加密密钥长期留在应用服务器内存;用“会话密钥”即可符合该条款,而根密钥仍留在 HSM 内。

“持久 / 会话 / 临时”是把风险暴露时间切成三档:

  • 持久 → 最小暴露面、最大合规成本;
  • 会话 → 平衡性能与安全;
  • 临时 → 极限性能、可接受的一次性风险。

密码芯片无法同时做到“绝对安全、无限容量、零延迟”,所以只能按生命周期分级,各取所长。

会话密钥负责“会话内不泄密”,持久密钥负责“跨会话还能认人”。
两者缺一不可:没有会话密钥,通信效率低且容易泄露长期秘密;没有持久密钥,则无法建立长期身份与信任链。
会话密钥解决“会话级”安全,临时密钥再砍一刀,解决“瞬时级”安全与零资源占用。
两者并存,就是在“安全-性能-资源”三角里再细分出一个极致优化档位:
会话密钥够用就不上临时密钥;需要极限缩窗口、零持久化时,就让临时密钥顶上去。

“会话密钥+密钥封装”是国密SDF标准推荐的数据加密/解密业务流程,核心思想是:
数据不直接用非对称私钥解密,而是用对称会话密钥加密/解密,非对称密钥只用于加密/解密会话密钥(即密钥封装/解封装)。

典型流程如下:

  1. 发送方(加密方):
  • 生成一个随机的对称会话密钥(如SM4密钥)。
  • 用接收方的公钥(RSA或SM2)加密这个会话密钥,得到“密钥密文”(密钥封装)。
  • 用会话密钥对数据进行加密,得到“数据密文”。
  • 发送“密钥密文+数据密文”给接收方。
  1. 接收方(解密方):
  • 用自己的私钥解密“密钥密文”,恢复出会话密钥(密钥解封装)。
  • 用会话密钥解密“数据密文”,得到原始数据。

SDF接口实现举例(以ECC为例):

  • 生成会话密钥并用公钥加密输出:
    SDF_GenerateKeyWithEPK_ECC(或SDF_GenerateKeyWithIPK_ECC)
  • 用会话密钥加密数据:
    SDF_Encrypt
  • 用私钥解封装会话密钥:
    SDF_ImportKeyWithISK_ECC
  • 用会话密钥解密数据:
    SDF_Decrypt

这样,私钥始终不直接参与数据解密,提升了安全性,且支持大数据量加密。

总结:
“会话密钥+密钥封装”=“用非对称密钥加密/解密会话密钥+用会话密钥加密/解密数据”,是现代密码设备的主流安全设计。

你现在的分层思路是:

1
设备 → 会话 → 密钥

再加上“会话列表、容器列表”,已经形成 “三(或四)级句柄 + 两级目录” 的层级。
方向完全正确,而且与 SDF、PKCS#11、TPM 等主流硬件接口的设计逻辑一致。
之所以要设计成这样,是为了在 “并发、安全、资源、易用” 四个维度上同时做隔离与复用——本质上是一次 “空间换安全/并发” 的工程折中。


  1. 设备句柄(Device Handle)
    代表“一块物理/虚拟密码芯片”,一次打开→多次复用。
    • 做最粗粒度的权限与资源隔离
    – 谁可以开设备(进程/用户/容器)
    – 设备级全局配额(RAM、NVRAM、句柄总量)

  2. 会话句柄(Session Handle)
    代表“一个登录上下文”,解决多线程/多进程同时访问的问题。
    • 每个会话维护自己的:
    – 认证状态(已登录/未登录,User PIN 已验证?)
    – 会话级对象列表(密钥、证书、随机数)
    – 会话级错误码和原子操作锁
    • 典型场景:Web 服务器 100 个 worker 进程,每个进程各自开 1-N 个会话,互不阻塞。

  3. 密钥句柄(Key Handle)
    代表“一块受保护的密钥对象”,真正干活的最小单元。
    • 只在会话作用域内有效(有的实现在 Session 退出时自动销毁句柄,防止泄漏)。
    • 支持“持久对象”和“会话对象”两种属性,通过句柄属性位区分。

  4. 会话列表 & 容器列表(Session List / Container List)
    • 会话列表:设备级目录,用于 调试、审计、强制登出(管理员可踢掉某个会话)。
    • 容器列表(或对象列表):会话级目录,相当于 “当前会话可见的持久密钥/临时密钥索引表”,便于枚举、查找、清理。


为什么要这样分层?——把“四个矛盾”拆开:

  1. 并发 vs. 隔离
    设备只有一个,但上层有多进程/多线程。会话层把“全局状态”拆成“局部状态”,避免加全局大锁。

  2. 安全 vs. 易用
    密钥句柄只暴露 32/64 位整数,而不是裸露的密钥材料;
    会话退出或句柄关闭即可零成本“擦除”临时密钥,减少应用层忘记清内存的风险。

  3. 资源 vs. 扩展
    设备 RAM/句柄池有限。
    – 设备级配额:控制总句柄数,防止 DoS。
    – 会话级配额:单个会话泄漏不会拖垮整片芯片。
    – 密钥级属性:持久对象占 NVRAM,会话对象占 RAM,精确计费。

  4. 管理 vs. 审计
    会话列表让管理员可以查看“谁在用”“用了多少句柄”;
    容器列表让应用可以枚举“我有哪些密钥”,而无需遍历整块存储。


一张速查表

层级句柄/列表主要作用域生命周期典型操作
设备Device Handle / Device List系统级进程级open/close, getInfo
会话Session Handle / Session List设备级登录态login/logout, closeAll
密钥Key Handle / Container List会话级会话或持久create, use, destroy

结论
你现在的“设备 → 会话 → 密钥”三层 + 列表设计,正是为了在单块芯片上同时实现:
• 多用户并发、
• 密钥最小暴露、
• 资源可计量、
• 运维可管理。

这是密码硬件领域经过二十多年迭代后,最通用、最经得起工程检验的架构。


开源之夏-13
https://43.242.201.154/2025/08/21/开源之夏-13/
Author
Dong
Posted on
August 21, 2025
Licensed under