如何在Python ssl中查看失败连接的握手/证书信息?
获取Python SSL失败握手的TLS版本与证书信息
方法1:启用OpenSSL调试日志
Python的ssl模块基于OpenSSL,通过设置环境变量可直接捕获握手全过程的详细日志,包括失败场景下的版本协商、证书交换信息:
- 运行脚本前设置环境变量:
export OPENSSL_DEBUG_FILE=ssl_handshake.log export OPENSSL_CONF=/dev/null # 避免系统默认配置干扰 - 执行Python连接脚本后,
ssl_handshake.log中会记录握手各阶段细节,比如客户端发送的TLS版本、服务器返回的证书链、失败原因的底层信息,无需修改代码。
方法2:利用SSL上下文的信息回调
通过SSLContext.set_info_callback注册回调函数,在握手的各个阶段(包括失败前的步骤)输出关键信息:
import ssl import socket def ssl_handshake_callback(ssl_sock, where, ret): # 捕获握手开始阶段,打印客户端尝试的TLS版本 if where & ssl.SSL_CB_HANDSHAKE_START: print(f"客户端尝试的TLS版本: {ssl_sock.get_protocol_version_name()}") # 捕获证书接收阶段,获取原始证书数据 elif where & ssl.SSL_CB_CERTIFICATE: raw_cert = ssl_sock.getpeercert(binary_form=True) if raw_cert: print(f"收到服务器证书(原始DER格式长度: {len(raw_cert)})") # 可选:转换为PEM格式查看 pem_cert = ssl.DER_cert_to_PEM_cert(raw_cert) print("证书PEM格式:\n", pem_cert[:500] + "...") # 打印前500字符避免过长 # 配置SSL上下文(硬编码版本和CA) ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) ctx.load_verify_locations("your_ca.crt") ctx.min_version = ssl.TLSVersion.TLSv1_2 ctx.max_version = ssl.TLSVersion.TLSv1_2 # 注册回调 ctx.set_info_callback(ssl_handshake_callback) # 执行连接 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssl_sock = ctx.wrap_socket(sock, server_hostname="your_server.com") try: ssl_sock.connect(("your_server.com", 443)) except ssl.SSLError as e: print(f"握手失败: {str(e)}") finally: ssl_sock.close()
该回调会在握手的关键节点触发,即使最终握手失败,也能获取到客户端发起的TLS版本、服务器返回的证书原始数据。
方法3:抓包工具(Wireshark)
直接使用Wireshark在客户端或服务器机器上抓包,过滤tls协议:
- 查看
Client Hello包:获取客户端声明的TLS版本、加密套件等信息 - 查看
Server Hello和Certificate包:获取服务器选定的TLS版本、返回的证书链内容 - 即使握手失败,这些握手初期的数据包都会被捕获,直观呈现双方的交互细节
内容的提问来源于stack exchange,提问作者mwolfe 11
相关产品推荐
相关产品推荐

