无需OpenSSL,Python3.10标准库能否获取无效证书链?
问题解答
1. 仅用Python 3.10标准库能否获取无效证书链?
可以,但要注意:Python标准库的ssl模块底层依赖OpenSSL(Windows下为Schannel、macOS下为Secure Transport),无法完全脱离原生TLS实现。不过只要配置正确,就能获取终止于未知根的完整证书链——关键是在禁用证书验证的前提下,拿到服务器发送的所有证书数据。
2. 你的代码为什么返回空结果?
问题出在getpeercert()的默认行为:当verify_mode=CERT_NONE时,OpenSSL不会自动解析并返回证书链的结构化数据,所以返回空。另外你的代码还有个小bug:ssl_wrap_socket函数里引用了ssl.SSLError但没导入整个ssl模块,运行时会报错。
修复方案
方案一:获取原始二进制证书链
修改__main__函数的返回逻辑,用binary_form=True参数获取原始DER格式的证书链:
def __main__(hostname): with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: s.connect((hostname, 443)) sslSocket = ssl_wrap_socket(s, ssl_version=PROTOCOL_TLS_CLIENT, cert_reqs=CERT_NONE, check_hostname=False, server_hostname=hostname) # 获取原始二进制证书链(DER格式) return sslSocket.getpeercert(binary_form=True)
方案二:修复导入错误
在ssl_wrap_socket函数开头补充导入:
from ssl import SSLError
然后把raise ssl.SSLError(e)改成raise SSLError(e)。
3. 无需OpenSSL这类外部原生代码能否实现?
标准库做不到,因为官方ssl模块必须依赖原生TLS库。但有纯Python的第三方库可以实现,比如tlslite-ng——它完全用Python实现了TLS协议栈,不依赖任何原生代码。
这类纯Python库的实现逻辑是:
- 直接建立TCP连接,手动构造TLS握手的Client Hello消息并发送。
- 接收服务器的TLS响应,解析其中的Certificate消息,提取所有DER格式的证书。
- 用纯Python的ASN.1解析工具(如
pyasn1)解析证书的内容,不管证书是否可信都能完整获取链上的所有证书。
内容的提问来源于stack exchange,提问作者JamesTheAwesomeDude
相关产品推荐
相关产品推荐

