【发布时间】:2019-02-10 00:09:17
【问题描述】:
我需要从一堆具有自签名证书的设备中读取颁发者 CN。有些人有一个错误,即发行人 CN 在应该是唯一的时候并不是唯一的,我希望确定哪些人有这种情况。找到了一个代码片段here,稍作修改:
import ssl, socket
myhostname = 'some_host'
myctx = ssl.create_default_context()
myctx.check_hostname = False
myctx.verify_mode = ssl.CERT_NONE # ssl.CERT_OPTIONAL
s = myctx.wrap_socket(socket.socket(), server_hostname=myhostname)
s.connect((hostname, 443))
cert = s.getpeercert()
当 verify_mode 为 CERT_NONE 时,连接建立但证书被丢弃;当 CERT_OPTIONAL 连接失败时,因为验证失败。
如何在不使用 openssl 的情况下连接并读取错误证书的详细信息?
这是一个一次性的问题解决脚本;我只需要输出 some_host 和 issuer CN。 Openssl 在此系统上不可用。
编辑 1 遵循 Patrick 的 PyOpenSSL 建议(也不在此系统上)this post 表示 cert = s.getpeercert(binary_form=True) 以 DER 格式返回证书。
EDIT 2重复还是不重复?最终我认为是的,它是重复的,但不是指定的“重复”,因为我的系统上没有 Openssl。我相信还是有用的。下面的工作解决方案使用来自几个 other posts 的信息以及沿途的其他几个。整洁的一点是使用 ssl.get_server_certificate (感谢 Steffen,不需要 getpeercert;返回 pem 不是 der),而丑陋的一点是将证书存储到文件中,然后使用未记录的方法获取详细信息。它不使用 getpeercert 也不使用 openssl。
如果有一种更简洁的方法来处理收到的 pem 证书以阅读我很想知道的详细信息,但这对我来说已经足够了。
【问题讨论】:
-
您可能需要使用
PyOpenSSL库,您可以在其中在 TLS 握手的各个步骤中注入各种回调,从而访问交换的证书。