文章总结: 本文系统对比了GB/T35275与GM/T0010标准中SM2签名数据SignedData格式的关键差异,包括版本号、字段命名、内容封装结构和签名计算规则等方面的不一致性。通过真实案例指出这些差异可能导致跨系统解析失败,并给出明确标准选择、自适应解析、统一签名计算等避坑指南,帮助开发者避免互操作性问题。 综合评分: 88 文章分类: 技术标准,密码学,安全开发
那些年我们踩过的坑——SignedData
原创
利刃信安 利刃信安
利刃信安
2026年6月1日 11:11 北京
在小说阅读器读本章
去阅读
那些年我们踩过的坑——SignedData
摘要:在密码应用开发中,SM2 算法签名消息的封装格式一直是个“雷区”。国家标准 GB/T 35275 与行业标准 GM/T 0010 对
SignedData的定义存在多处关键差异:版本号不同、字段命名迥异、内容封装结构不一致、签名计算过程的描述详略悬殊。本文结合真实踩坑经历,系统梳理了这些差异,并给出了避坑指南,帮助开发者避免“同一种签名,两套解析”的尴尬局面。
一、故事的起因:两个标准,一个签名
某天,你兴奋地拿到了一个 SM2 签名数据包,按照 GB/T 35275 文档编写了解析代码,顺利通过自测。然而,当这个数据包被送到另一个系统验证时,对方却报出“格式错误”“签名验证失败”。你翻遍代码,怀疑人生——最后发现,对方用的是 GM/T 0010 标准。
这种情况在密码行业并不罕见。GB/T 35275(国家标准)和 GM/T 0010(密码行业标准)虽然都定义了 SM2 密码算法的加密签名消息格式,但两者的 SignedData 部分存在诸多“微妙”差异。这些差异就像地雷,一不小心就会炸翻你的生产环境。
二、第一个坑:版本号——1 还是 2?
打开两个标准,先看 SignerInfo 的版本号:
| 标准 | SignerInfo 版本号 | 备注 |
| — | — | — |
| GB/T 35275-2026 | 2 | 从 2017 版的 1 改为 2 |
| GM/T 0010-2023 | 1 | 保持原有值 |
这意味着什么?如果你按 GB/T 35275 生成签名,SignerInfo.version 字段值为 2;而按 GM/T 0010 解析的代码可能只接受值为 1。结果就是解析失败,或者被强制转换为 1 导致后续校验混乱。
真实案例:某 CA 系统升级后,签名数据被下游应用拒收,排查两天才发现版本号不一致。最终被迫在两端同时支持两种版本号,并通过协商机制决定使用哪个标准。
三、第二个坑:字段名称和结构差异
你以为只是版本号不同?太天真了。看看 SignedData 的核心结构:
| 字段 | GB/T 35275-2026 | GM/T 0010-2023 |
| — | — | — |
| 内容封装 | encapContentInfo | contentInfo |
| 签名算法标识 | signatureAlgorithm | digestEncryptionAlgorithm |
| 签名值 | signature | encryptedDigest |
| 待签名属性 | signedAttrs | authenticatedAttributes |
| 未签名属性 | unsignedAttrs | unauthenticatedAttributes |
更致命的是,encapContentInfo 和 contentInfo 的结构完全不同:
- • GB/T 35275:
EncapsulatedContentInfo包含eContentType和eContent(显式 OCTET STRING)。 - • GM/T 0010:
ContentInfo包含contentType和content(ANY,由 contentType 决定)。
某次对接中,开发人员直接复用了一个 GM/T 0010 的解析库去解析 GB/T 35275 数据,结果在 eContent 字段上崩溃——因为 GM/T 0010 根本不知道 eContent 是什么。
四、第三个坑:签名计算过程的“罗生门”
签名计算是 SignedData 的核心。两个标准都允许 signedAttrs(或 authenticatedAttributes)存在或不存在,但细节天差地别:
GB/T 35275 的明确要求
若
signedAttrs存在,则待签名数据为signedAttrs的 DER 编码结果,且signedAttrs必须包含messageDigest属性,其值为eContent的 SM3 杂凑值。 若signedAttrs不存在,则待签名数据为eContent的内容(不包括 DER 标签和长度)。
GM/T 0010 的模糊描述
若
authenticatedAttributes存在,该域中摘要的计算方法是对原文进行摘要计算结果。
这里的“原文”是什么?是对 content 的内容做摘要,还是对 authenticatedAttributes 自身做摘要?标准没有明确说 authenticatedAttributes 必须包含 messageDigest,也没有说明如何组织待签名数据。这导致不同厂商的实现五花八门:
- • 厂商 A:将
authenticatedAttributes的 DER 编码作为签名输入(与 GB/T 35275 一致)。 - • 厂商 B:直接将
content的摘要签名,再放入authenticatedAttributes中作为属性(但属性集合本身不参与签名)。 - • 厂商 C:干脆忽略
authenticatedAttributes,永远使用无属性签名。
后果:同一个签名数据,在不同实现下验证结果可能完全相反。
五、第四个坑:隐式证书的“隐身术”
GM/T 0010-2023 在附录 B 中增加了隐式证书相关数据类型(imcSignedData、imcEnvelopedData 等),而 GB/T 35275-2026 完全不支持隐式证书。如果你以为两个标准完全兼容,直接拿 GM/T 0010 的隐式证书数据去给 GB/T 35275 解析,结果必然是“找不到 OID”或“格式错误”。
六、避坑指南
1. 明确你遵循的是哪个标准
- • 如果是商用密码应用,通常遵循 GM/T 0010(行业标准更早普及)。
- • 如果是金融、政务等强调国标兼容的场景,可能要求 GB/T 35275。
- • 最稳妥的方式:在协议或配置文件中明确标注使用的标准版本。
2. 自适应解析
建议实现一个兼容两层标准的解析器:
- • 读取
SignerInfo.version:若为 1,按 GM/T 0010 解析;若为 2,按 GB/T 35275 解析。 - • 通过 OID 判断内容封装类型(
encapContentInfovscontentInfo)。
3. 签名计算统一化
强烈建议统一采用带有 signedAttrs 且包含 messageDigest 的方式,因为这种方式最安全、最规范,且 GB/T 35275 已明确要求。GM/T 0010 虽未强制,但实际行业实践中大多数实现也遵循此方式。
4. 版本号协商
如果需跨系统互操作,可增加一个握手阶段,交换双方支持的 SignedData 版本号,然后按对应版本生成/解析。
5. 工具链统一
尽可能使用同一套密码库(如 GMSSL、OpenSSL 的 SM2 扩展),并在库层面做统一抽象。避免手动拼接 ASN.1 结构。
七、结语
“踩坑”的根源,在于标准演进过程中留下的历史包袱。GB/T 35275-2026 相比旧版改动较大(版本号从 1 改 2、增加了 AuthEnvelopedData 等),而 GM/T 0010-2023 保持了更多旧版结构。两者之间的差异并非不可调和,但需要开发者保持警惕。
记住:不要默认“所有 SM2 签名数据格式都一样”。下次再收到一个 SignedData,先问一句:“这是按哪个标准封装的?版本号是多少?”——这简单的一问,能帮你省下至少两个通宵。
愿天下没有难解析的签名数据。
附录:关键差异速查表
| 项目 | GB/T 35275-2026 | GM/T 0010-2023 |
| — | — | — |
| SignedData 版本 | 1 | 1 |
| SignerInfo 版本 | 2 | 1 |
| 内容封装 | encapContentInfo | contentInfo |
| 签名算法标识 | signatureAlgorithm | digestEncryptionAlgorithm |
| 签名值字段 | signature | encryptedDigest |
| 签名属性字段 | signedAttrs | authenticatedAttributes |
| 隐式证书支持 | 无 | 有(附录 B) |
| 签名计算详细度 | 高(明确指定 DER 编码) | 低(描述模糊) |
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:利刃信安 利刃信安 利刃信安《那些年我们踩过的坑——SignedData》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。







评论