arch
(Evan(bx))
1
背景:
openubmc使用的是 华为 openUBMC 工程自带的 hpm_signer 工具,用于对固件镜像(如 uboot.bin)进行签名,并通过本地 tsa.cnf 配置添加 RFC 3161 时间戳,形成一个完整的 CMS Detached 签名 + 时间戳结构(即 CAdES-T)。目前这套流程效果如下:
hpm_signer 实际做了哪些操作?
我们直接拿cms文件用openssl查看结构后确认,它完成了如下完整签名流程:
| 步骤 |
说明 |
① 读取cms文件,如 uboot.bin.cms |
|
| ② 计算 SHA-256 摘要 |
|
③ 构造 CMS SignedData 结构,签名算法为 sha256WithRSAEncryption,生成 Detached 签名(不嵌入原始内容) |
|
④ 添加 SignedAttributes:包括 contentType、signingTime、messageDigest、id-smime-aa-signingCertificateV2 |
|
⑤ 使用 RSA 私钥签名 SignedAttributes |
|
| ⑥ 将签名值进行 SHA-256 摘要 |
|
⑦ 根据 tsa.cnf 配置,通过本地 HTTP 或本地私钥生成 RFC 3161 TimeStampToken |
|
⑧ 将时间戳(TimeStampToken)封装为 UnsignedAttributes,OID 为 1.2.840.113549.1.9.16.2.14(即 signatureTimeStampToken) |
|
⑨ 输出最终 CMS 签名文件:例如 uboot.bin.cms |
|
签名结果结构见 openssl cms -inform DER -cmsout -print 可确认,确实嵌入了 RFC 3161 时间戳。
问题:
我们希望将签名操作迁移至云签名架构,即使用 SignServer 作为 TSA 或 CMS 签名服务。
但发现如下问题:
hpm_signer 当前必须依赖本地 tsa.cnf 文件;
- 而 SignServer 提供的是基于 HTTP 接口的 TSA,不会提供
.cnf 文件;
- 因此初步判断,要替换掉
hpm_signer,要么需要重写它,要么需要替代工具完成类似功能吗。
我想请教社区以下问题:
- 是否有大佬实现过类似迁移,把
hpm_signer 的 TSA 机制替换为 SignServer(例如通过 SignServer 的 Extended CMS Signer 或其他接口)?
- 是否有办法用
openssl cms、openssl ts 等命令结合脚本完成同样流程(包括时间戳嵌入)?
- 如果要重写一个精简版的
hpm_signer,是否有示例代码?
arch
(Evan(bx))
2
我们目前的证书和签名服务器不是基于 OpenSSL 的,也没有 tsa.cnf 文件,因此现有的 hpm_signer 不太适配。
但应该是支持通过 OpenSSL 调用 URL 方式发起签名请求,在其他帖子上有验证。
能否提供 hpm_signer 内部对应的 OpenSSL 命令步骤,方便我们评估是否可通过修改命令适配现有流程?
arch
(Evan(bx))
5
测试背景:
我用如下命令(OpenSSL 3.0.13,Ubuntu 24.04)重新生成了签名:
openssl cms -sign -binary \
-signer signer.pem -inkey signer.pem -in uboot.bin -md sha256 -cades \
-nosmimecap -outform DER -out step.cms
然后用 hpm_verify 进行验证:
hpm_verify -r rootca.pem -C cms.crl.pem -c uboot.bin -s step.cms
结果:Verification successfully 
但我注意到,这个 step.cms 文件:
- 完全是 OpenSSL 生成的;
- 没有添加时间戳(没有
unsignedAttrs,没有 OID 1.2.840.113549.1.9.16.2.14);
- 和
hpm_signer 最终生成的 .cms(含时间戳)在结构上有明显差异。
arch
(Evan(bx))
6
目前来看,OpenSSL 的本地时间戳签名流程(基于 tsa.cnf 配置)中,通常需要手动提取 CMS 中的签名值作为时间戳请求输入;签名完成后,还需通过工具将时间戳重嵌入 CMS。从现有实现看,hpm_signer 内部似乎是直接通过 OpenSSL 库将时间戳 token 写入 CMS 的。
但如果使用云端或第三方签名中心(非 OpenSSL TSA),则一般不依赖 tsa.cnf,签名值的提取步骤可能也不是必要的(这部分仍有待验证)。
不过仍有一个问题:在使用外部签名中心返回的时间戳 token(.tsr)时,是否仍需要依赖 OpenSSL 库将其注入原始 CMS 中?
arch
(Evan(bx))
9
需要进行二次嵌入,使用openssl库,因为24.04的openssl版本过于低。
目前使用openssl命令签名+生成时间戳token+openssl库的C代码实现签名+二次嵌入CMS验证目前应该是没问题。
后续需要将tsa.cnf文件删除,时间戳签名使用openssl+url配合云签名中心
arch
(Evan(bx))
10
通过重新学习 SignServer 的架构后了解到:在开源社区版中,虽然支持基础 CMS 签名和时间戳响应(TSR)的生成,但仍需基于签名值手动创建时间戳请求(TSQ)再获取 TSR,再手动将其嵌入至 CMS 签名中,即仍需二次处理签名结果。而在企业付费版中,提供了更高的集成度,可通过一条 curl 命令自动完成 TSQ 生成、TSR 请求及其注入 CMS 签名的全过程,显著简化操作流程。
Larry_Li
(LiJiang)
11