You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用asn1tools解码X.509证书报错的问题排查咨询

纯Python实现X.509证书全信息提取问题排查

已完成前置工作

  • 参考Python官方ssl模块文档,实现了支持IPv4/IPv6双栈的套接字客户端,加载了www.python.org对应的证书bundle;参考本地证书颁发者校验报错的解决方案,下载证书链拆分保存为独立文件,添加context.load_verify_locations('path/to/cabundle.pem')配置后客户端可正常运行,所用证书均合法有效。
  • 参考X.509公钥证书信息打印方案,计划使用如下代码实现解码:
    import asn1tools
    foo = asn1tools.compile_files("x509.asn")
    output = foo.decode("Certificate", cert)
    
    该代码逻辑依赖对应的X.509 ASN.1定义文件。
  • 从ITU官方下载了ITU-T X.509 (08/1997)标准规范压缩包,解压得到三个文件:AlgorithmObjectIdentifiers.asn、AuthenticationFramework.asn、CertificateExtensions.asn。最初误将AlgorithmObjectIdentifiers.asn作为顶层定义文件传入编译函数,执行代码如下:
    foo = asn1tools.compile_files("AlgorithmObjectIdentifiers.asn")
    output = foo.decode("Certificate", cert)
    print("Cert output: ", output)
    

运行报错信息

File ".../test-print-ssl.py", line 47, in cert_print_asn1
    output = foo.decode("Certificate", cert)
  File "...\lib\site-packages\asn1tools\compiler.py", line 161, in decode
    "Type '{}' not found in types dictionary.".format(name))
asn1tools.errors.DecodeError: Type 'Certificate' not found in types dictionary.

待解决疑问

  • 从哪里可以获取适用于上述代码的有效ASN.1文件?
  • 已经下载的三个ASN.1文件应如何正确使用?是否需要合并文件?如果需要合并应如何操作?
  • 应当如何进一步调试排查该问题?

补充说明

  • 已验证openssl x509 -in website.com.pem -text命令可正常打印同一份证书文件的内容,知晓可以通过os.system()调用openssl命令实现需求,但希望获得纯Python实现的证书解码打印方案。
  • 已查阅过asn1tools编译ASN.1失败的相关问题,本次报错发生在解码阶段,与编译失败的场景并不相同。

解决方案

1. 有效ASN.1文件获取

你从ITU官方下载的三个1997版X.509规范文件本身就是合法有效的ASN.1定义源,不需要额外找其他零散的x509.asn文件。网上流传的单文件x509.asn大多是开发者提前合并好依赖的版本,反而容易出现OID缺失、扩展定义不全的问题。

2. 三个ASN.1文件的使用方法

不需要手动合并文件。asn1tools.compile_files本身支持传入文件路径列表,会自动解析处理文件间的依赖引用。
三个文件的层级关系如下:

  • AlgorithmObjectIdentifiers.asn:存储通用算法对象标识符(OID)定义,为最底层依赖
  • CertificateExtensions.asn:存储X.509 v3证书的扩展字段定义,依赖算法OID文件
  • AuthenticationFramework.asn:包含Certificate类型的顶层定义,依赖前两个文件

正确的编译写法如下:

import asn1tools
# 直接传入所有ASN.1文件即可,工具会自动处理依赖顺序
compiler = asn1tools.compile_files([
    "AlgorithmObjectIdentifiers.asn",
    "CertificateExtensions.asn",
    "AuthenticationFramework.asn"
])

如果确实需要合并为单文件,按照「算法OID文件→证书扩展文件→认证框架文件」的顺序,把三个文件的内容依次拼接为同一个.asn文件即可,注意删除重复的模块声明头部。

3. 调试排查步骤

  • 第一步校验编译后的可用类型:编译完成后执行print(compiler.types.keys()),即可看到当前编译产出的所有支持解析的ASN.1类型。你之前的报错核心原因就是只传入了算法OID定义文件,该文件内根本没有定义Certificate类型,自然会提示类型不存在。
  • 第二步校验证书输入格式:如果是读取PEM格式证书,需要先去掉-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----的头尾标记,将剩余内容做base64解码得到DER格式的二进制字节串,再传入decode方法,直接传入PEM文本会导致解码失败。
  • 第三步适配编码兼容性:如果遇到部分扩展字段解码报错,可以在编译时添加numeric_enums=True参数,解码时指定encoding='der',适配不同CA签发证书时的编码实现差异。

额外纯Python实现方案

如果不想手动维护ASN.1定义文件,可以直接使用纯Python实现的cryptography库加载解析证书,不需要调用外部openssl命令,直接访问对象属性即可拿到所有证书信息,示例代码:

from cryptography import x509
from cryptography.hazmat.backends import default_backend

with open("website.com.pem", "rb") as f:
    cert_data = f.read()
cert = x509.load_pem_x509_certificate(cert_data, default_backend())
# 可直接访问subject、issuer、extensions、public_key、serial_number等所有证书字段
print(cert)

内容的提问来源于stack exchange,提问作者minghua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 23:42:25