首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尽管Python中的握手失败,仍可获取服务器证书

尽管Python中的握手失败,仍可获取服务器证书
EN

Stack Overflow用户
提问于 2020-05-12 03:35:42
回答 2查看 218关注 0票数 2

我正在写一个监控服务器证书过期的工具。我正在使用python3 ssl和套接字模块来获取服务器证书,使用的是一个非常基本的方法:创建默认上下文,禁用主机名验证和证书验证,调用SSLSocket.connect(),然后调用SSLSocket.getpeercert(),唯一的目的就是获取服务器证书,仅此而已。

这一切都是在私有网络中进行的,我不关心验证。

我有一些设备需要由私有CA签名的客户端证书(我的工具没有),因此在SSLSocket.connect()上握手失败,使得SSLSocket.getpeercert()不可能实现。

我知道在握手期间,服务器证书确实被提供给了我的客户端(连同那个令人讨厌的证书请求)。我可以在数据包捕获中看到它,也可以只使用openssl s_client命令行。

这是我的代码。

代码语言:javascript
复制
def get_cert(self, host, port):
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    with ctx.wrap_socket(socket.socket(), server_hostname=host) as s:
        s.settimeout(10)
        s.connect((host, port))
        binary_cert = s.getpeercert(True)
        cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, binary_cert)
        pem_cert = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert).decode()
        return pem_cert

有没有办法在握手消息中降低一点,以获得服务器证书,即使握手最终失败了?

我目前的解决方案是在发生ssl.SSLError的情况下使用subprocess.run()运行openssl s_client -connect host:port

EN

回答 2

Stack Overflow用户

发布于 2020-08-31 22:03:24

您可以捕获do_handshake()产生的异常,然后继续处理服务器证书。

代码语言:javascript
复制
import OpenSSL
import socket

dst = ('10.10.10.10', 443)
sock = socket.create_connection(dst)
context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
connection = OpenSSL.SSL.Connection(context, sock)
connection.set_connect_state()
try:
  connection.do_handshake()
except:
  print(connection.get_peer_cert_chain())

在python 2.7.17和3.8.5上测试

票数 1
EN

Stack Overflow用户

发布于 2021-10-20 09:17:36

不幸的是,在低于3.10的版本中,python的ssl模块似乎无法做到这一点。在这些版本中,获取我能看到的对等证书的唯一方法是通过低级_ssl.SSLSocket.getpeercert()方法,如果握手没有完成,它会立即抛出异常。

从Python3.10开始,有了一个新的_ssl.SSLSocket.get_unverified_chain()方法,它不做握手检查,所以也许像这样令人讨厌的东西可以工作?

代码语言:javascript
复制
ssock = context.wrap_socket(sock, do_handshake_on_connect=False)

try:
    ssock.do_handshake()
except ssl.SSLError as e:
    pass

certs = ssock._sslobj._sslobj.get_unverified_chain()

..。但我还没有测试过。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61737856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档