读取X.509 v3证书扩展时出现额外前缀字节的原因是什么?
问题原因解答
你看到的开头字节并非多余内容,是X509扩展值的标准ASN.1 DER编码格式的组成部分:
所有X509证书的扩展值都采用TLV格式的ASN.1 DER编码存储,结构分为三部分:
- 第一个字节:标签(Tag),标识数据的类型,比如
0x0C对应UTF8字符串、0x03对应比特串、0x30对应序列结构 - 第二个字节:长度(Length),标识后续实际数据的字节长度(短编码场景下长度仅占1字节,超过127字节的内容长度会占多字节)
- 后续字节:实际值(Value),就是你要读取的明文内容
你输出里的自定义扩展b'\x0c\x05User1'就完全符合这个结构:
0x0c:UTF8String类型标签0x05:后续值长度为5字节- 后5字节:就是你写入的
User1内容
其他扩展的开头字节也遵循同样规则,比如密钥用法扩展的b'\x03\x02\x05\xe0',0x03是比特串标签,0x02是后续值长度2字节。
修正后的读取代码
如果你要提取自定义扩展的明文内容,直接去掉前2个字节即可,针对你的场景代码可修改为:
from OpenSSL import crypto as c cert = c.load_certificate(c.FILETYPE_PEM, open('./client.crt').read()) count = cert.get_extension_count() # 你自定义扩展的OID CUSTOM_EXT_OID = "1.2.3.4.5.6.7.8" print(count) for i in range(0, count): ext = cert.get_extension(i) # 获取扩展的OID字符串 ext_oid = ext.get_object().oname() data = ext.get_data() print(f"扩展OID: {ext_oid}, 原始编码: {data}") # 匹配自定义OID后提取内容 if ext_oid == CUSTOM_EXT_OID: content = data[2:].decode('utf8') if content == "User1": print("User1 found!") else: print("User1 not found!")
如果要解析其他标准扩展(比如SAN、密钥用法等),使用专门的ASN.1解析库按对应结构解析即可。
内容的提问来源于stack exchange,提问作者George Makrakis
相关产品推荐
相关产品推荐

