当SSL:certificate\u verify\u失败时获取证书信息

2024-09-20 03:53:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要从一堆具有自签名证书的设备中读取颁发者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的情况下连接并从错误的证书中读取详细信息?在

这是一个一次性的问题解决脚本;我只需要输出一些主机和颁发者CN。Openssl在此系统上不可用。在

edit1遵循Patrick的PyOpenSSL建议(也不在本系统中)this post表示{}以DER格式返回证书。在

编辑2复制还是不复制?最终我认为是的,它是一个复制品,但不是指定的“复制品”,因为我的系统上没有Openssl。我相信它还是有用的。下面的工作解决方案使用来自多个otherposts的信息,以及一路上其他几个人的信息。整洁的位子正在使用ssl.get_服务器_证书(感谢Steffen,不需要getpeercert;返回pem not der)而难看的部分是将证书存储到文件中,然后使用未记录的方法获取详细信息。它不使用getpeercert,也不使用openssl。在

如果有一种更简洁的方法来处理收到的pem证书的详细信息,我很想知道,但它对我来说已经足够好了。在


Tags: sslcertmode系统错误情况详细信息socket
2条回答

下面的代码执行此操作,但将证书写入文件。是否可以直接解码证书并避免将其保存到文件中?

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)

编辑更简单,但仍然写入文件

^{pr2}$

因为您说过这是一个一次性的问题解决脚本,而且您缺少许多组件来用python本机完成此任务。shell脚本是否可以接受(或者使用python执行和读取shell/system命令)?如果有,并且curl可用,您可以尝试这样使用它:

    curl -vvI https://www.google.com

* About to connect() to www.google.com port 443 (#0)
*   Trying 172.217.197.103...
* Connected to www.google.com (172.217.197.103) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*   subject: CN=www.google.com,O=Google LLC,L=Mountain View,ST=California,C=US
*   start date: Aug 14 07:44:35 2018 GMT
*   expire date: Oct 23 07:38:00 2018 GMT
*   common name: www.google.com
*   issuer: CN=Google Internet Authority G3,O=Google Trust Services,C=US
> HEAD / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.google.com
> Accept: */*

如果没有openssl来运行s_客户机来保存/解析证书,这是想到的最简单的事情,可以快速获取颁发者并以您喜欢的任何方法解析它。

相关问题 更多 >