我需要从一堆具有自签名证书的设备中读取颁发者 CN。有些存在错误,导致发行人 CN 在其应有的情况下并不唯一,我希望确定哪些发行人具有此条件。我在这里找到了一个代码片段并稍微修改了一下:
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()
Run Code Online (Sandbox Code Playgroud)
当 verify_mode 为 CERT_NONE 时,建立连接但证书被丢弃;当 CERT_OPTIONAL 时,由于验证失败,连接失败。
如何在不使用 openssl 的情况下连接并读取错误证书的详细信息?
这是一个一次性解决问题的脚本;我只需要输出 some_host 和颁发者 CN 。Openssl 在此系统上不可用。
编辑 1按照帕特里克的PyOpenSSL建议(也不在这个系统上)这篇文章表明cert = s.getpeercert(binary_form=True)以 DER 格式返回证书。
EDIT 2重复还是不重复?最终我认为是的,它是一个重复项,但不是指定的“重复项”,因为我的系统上没有 Openssl。我相信它还是有用的。下面的工作解决方案使用了其他几篇 文章中的信息以及沿途的其他一些文章。巧妙的一点是使用 ssl.get_server_certificate (感谢 Steffen,不需要 getpeercert;返回 pem 而不是 der),而丑陋的一点是将证书存储到文件中,然后使用未记录的方法来获取详细信息。它不使用 getpeercert 也不使用 openssl。
如果有一种更简洁的方法来处理收到的 pem 证书以阅读详细信息,我很想知道,但这对我来说已经足够好了。
下面的代码完成了这项工作,但将证书写入文件。是否可以直接解码证书并避免将其保存到文件中?
import ssl, socket
myhostname = 'some_host'
myctx = ssl.create_default_context()
myctx.check_hostname = False
myctx.verify_mode = ssl.CERT_NONE
s = myctx.wrap_socket(socket.socket(), server_hostname=myhostname)
s.connect((myhostname, 443))
bcert = s.getpeercert(binary_form=True)
cert = ssl.DER_cert_to_PEM_cert(bcert)
# workaround, ssl._ssl._test_decode_cert method expects a filename
f = open('mycert.pem','w')
f.write(cert)
f.close()
cert_dict = ssl._ssl._test_decode_cert('mycert.pem') # expects a filename?
subject = dict(x[0] for x in cert_dict['subject'])
issued_to = subject['commonName']
issuer = dict(x[0] for x in cert_dict['issuer'])
issued_by = issuer['commonName']
print(issued_to)
print(issued_by)
Run Code Online (Sandbox Code Playgroud)
编辑更简单,但仍然写入文件
import ssl
myhostname = 'some_host'
FILE = 'cert.pem'
with open(FILE, 'w', encoding='utf8') as fp:
fp.write(ssl.get_server_certificate((myhostname, 443)))
cert_dict = ssl._ssl._test_decode_cert(FILE)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4377 次 |
| 最近记录: |