X.509 证书密码应用标识合规检查实战:基于 GM/T 0006-2023 与 GB/T 33560-2026 构建国密标识验证工具

实践教程 · 2026-07-23 · 11 阅读

前言

在密评(商用密码应用安全性评估)工作中,最基本也最关键的一步是"摸清家底":你的系统用了哪些密码算法?是国密 SM2/SM3/SM4,还是国际算法 RSA/SHA/AES?这些算法在证书、协议、数据中如何标识?

2023年发布的 GM/T 0006-2023《密码应用标识规范》 和 2026年发布的 GB/T 33560-2017《网络安全技术 密码应用标识》 为这类问题提供了标准答案。它们定义了统一的算法标识体系和 OID 编码规则,让密码资产的识别有了"标尺"。

本文将基于这两个标准,用 Python 构建一个 X.509 证书密码应用标识合规检查工具。输入一个证书文件(PEM/DER),自动提取其中的算法 OID,对照国密标识表进行合规判断,并输出密评友好的审计报告。

环境准备

BASH
# Python 3.10+ 即可,仅依赖 cryptography 库
pip install cryptography>=41.0
版本要求cryptography 41+ 支持 SM3 哈希算法。本文代码基于 cryptography 42.x 编写。

标准速查:国密算法 OID 体系

根据 GM/T 0006-2023 和 GB/T 33560-2017,国密算法的核心 OID 定义如下:

OID算法/用途来源标准
1.2.156.10197.1.301SM2 椭圆曲线公钥(公钥加密、密钥交换)GM/T 0003.1-2023
1.2.156.10197.1.501SM2-with-SM3 数字签名GM/T 0003.2-2023
1.2.156.10197.1.502SM4 分组密码GB/T 32905-2016
1.2.156.10197.1.503SM2 密钥交换协议GM/T 0003.3-2023
1.2.156.10197.1.504SM3 密码杂凑算法GB/T 32907-2016
1.2.156.10197.1.601SM9 标识密码签名GM/T 0044.1-2023
1.2.156.10197.1.401ZUC 128 序列密码GM/T 0001-2012
注意:GM/T 0003 系列(2012版)在 2023 年进行了修订,从 2012 版的 "SM2 椭圆曲线公钥密码算法" 总集拆分为 5 个子标准(GM/T 0003.1 ~ 0003.5-2023),OID 体系保持不变。
国际算法的典型 OID 对比:

OID算法/用途
1.2.840.113549.1.1.11sha256WithRSAEncryption
1.2.840.10045.2.1id-ecPublicKey(ECDSA 公钥)
1.2.840.10045.4.3.2ecdsa-with-SHA256
2.16.840.1.101.3.4.2.1sha256 (纯哈希)

工具设计

整体架构

CODE
证书文件 (PEM/DER)
    ↓
X.509 解析层 (cryptography)
    ↓
OID 提取层 (算法/公钥/扩展)
    ↓
标识匹配层 (GM/T 0006-2023 + GB/T 33560-2017)
    ↓
合规检查层 (规则引擎)
    ↓
审计报告层 (JSON/Console)

核心数据结构

完整实现

代码说明

核心模块

模块功能依赖
GM_ALGORITHM_OIDS国密算法 OID 字典(GM/T 0006-2023 定义)纯静态数据
load_certificate()加载 PEM/DER 格式证书cryptography.x509
get_algorithm_identifier()OID → 算法名称 + 国密判断字典查找
get_public_key_info()解析公钥类型和长度cryptography.hazmat.primitives.asymmetric
check_compliance()多维度合规检查核心逻辑
generate_report()生成结构化 JSON 报告
print_report()控制台彩色格式化输出

检查规则

  • CRITICAL(关键项):签名算法为国密 + 公钥算法为国密 → 必须全部通过才算合规
  • WARN(警告项):密钥长度足够 + SAN 扩展存在 → 不通过会降级为"部分合规"
  • INFO(参考项):证书有效期 ≤ 395 天 → 仅作建议,不影响合规结论

运行验证

测试 1:自签 RSA 证书(预期:不合规)

BASH
python3 cert_identifier_checker.py /tmp/test_international.pem

预期输出

  • 签名算法: sha256WithRSAEncryption → ❌ 非国密
  • 公钥算法: RSA (2048 bits) → ❌ 非国密
  • 合规结论: ❌ 不合规 (NON_COMPLIANT)

测试 2:模拟 SM2 证书 OID 匹配(通过构造展示)

注意:由于 cryptography 当前版本不支持 SM2 曲线的原生生成(ec.SM2() 不存在),以下测试仅展示 OID 识别逻辑。实际 SM2 证书需使用 GmSSL、Tongsuo 或国密密码机生成。
PYTHON
# 测试 OID 识别函数
test_oids = [
    "1.2.156.10197.1.501",   # SM2-with-SM3
    "1.2.840.113549.1.1.11",  # sha256WithRSAEncryption
    "1.2.156.10197.1.504",   # SM3
]

for oid in test_oids:
    name, category, is_gm, source = get_algorithm_identifier(oid)
    print(f"  {oid} → {name} | 国密={is_gm} | {source}")

预期输出

CODE
1.2.156.10197.1.501 → SM2-with-SM3 数字签名 | 国密=True | GM/T 0006-2023 / GB/T 33560-2017
1.2.840.113549.1.1.11 → sha256WithRSAEncryption | 国密=False | 国际算法
1.2.156.10197.1.504 → SM3 密码杂凑算法 | 国密=True | GM/T 0006-2023 / GB/T 33560-2017

典型输出报告

扩展思路

1. 从证书扩展到 TLS 握手

PYTHON
# 在 TLS ClientHello 中解析国密密码套件
GM_CIPHER_SUITES = [
    "TLS_SM4_GCM_SM3",       # 国密 GCM 套件
    "TLS_SM4_CCM_SM3",       # 国密 CCM 套件
]

2. 批量扫描 PKI 资产

3. 集成到 CI/CD 流水线

YAML
# GitLab CI 示例
cert-compliance-check:
  script:
    - python cert_identifier_checker.py $CERT_PATH --json report.json
    - cat report.json | jq '.compliance.overall' | grep -q "COMPLIANT"
  artifacts:
    paths:
      - report.json

踩坑记录

1. cryptography 不支持 ec.SM2()

现象:尝试 ec.generate_private_key(ec.SM2())AttributeError: module 'cryptography.hazmat.primitives.asymmetric.ec' has no attribute 'SM2'

原因cryptography 库(截至 44.x)仅实现了 NIST/SECG 曲线,未内置 SM2 曲线参数。

解决:使用 GmSSL、Tongsuo 国密 OpenSSL 或国密密码机生成 SM2 证书,本工具仅做"识别和检查",不涉及 SM2 密钥生成。

2. 证书时间比较的 TypeError

现象cert.not_valid_after - datetime.now()TypeError: can't subtract offset-naive and offset-aware datetimes

原因datetime.now() 返回 naive datetime(无时区信息),而 cert.not_valid_after 在不同 cryptography 版本中的行为不一致。

解决:统一使用 datetime.now(timezone.utc) 获取 aware datetime,或使用 cert.not_valid_after_utc(cryptography 42+)。

3. OID 匹配的精度问题

现象:某些证书的签名算法 OID 是 1.2.840.113549.1.1.11(SHA256withRSA),但密钥是 RSA 2048,而国际算法也满足长度要求,容易被误判为"勉强合规"。

解决:将"签名算法"和"公钥算法"拆为两个独立 CRITICAL 检查项。只要有一个不是国密,整体结论就是 NON_COMPLIANT。密钥长度仅作为 WARN 项。

总结

GM/T 0006-2023 和 GB/T 33560-2017 为密码资产的标识提供了统一的标准语言。本文构建的 X.509 证书密码应用标识合规检查工具,能够:

  • 自动识别证书中的签名算法和公钥算法 OID
  • 对照标准判断是否为国密算法(SM2/SM3/SM4/SM9/ZUC)
  • 生成报告输出结构化 JSON,支持 CI/CD 集成
  • 批量扫描适用于企业 PKI 资产盘点和密评自查
对于正在进行国密改造的企业,这类工具可以作为密码资产清单(CBOM)的前置输入,帮助快速定位"哪些证书还是国际算法,需要替换为 SM2"。

参考来源

相关实践