You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3 SSL握手失败求助:SSLV3_ALERT_HANDSHAKE_FAILURE

SSL握手失败(SSLV3_ALERT_HANDSHAKE_FAILURE)排查与解决

问题重现

尝试实现SSL握手并提取服务器证书的SubjectName/CommonName时,触发如下错误:

File "/usr/lib/python3.10/ssl.py", line 1342, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)

已尝试的解决方案(均无效)

  • 猴子补丁跳过证书验证:
    ssl._create_default_https_context = ssl._create_unverified_context
    
  • 禁用SSL上下文的主机名检查与证书验证:
    sslContext.check_hostname = False
    sslContext.verify_mode = ssl.CERT_NONE
    
  • 使用自定义加密套件(字符串存在截断错误):
    cipher = (':ECDHE-RSA-AES128-GCM-SHA256:DES-CBC3-SHA:AES256-SHA:AES128-SHA:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256:ECDHE-RSA-DES-CBC3:EDH-RSA-DES-CBC3:EECDH+AESGCM:EDH-RSA-DES-CBC3-SHA:EDH-AESGCM:AES256+EECDH:ECHDE-RSA-AES256-GCM-SHA384:ECHDE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECHDE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-A$:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK')
    sslContext.set_ciphers(cipher)
    
  • 配置OpenSSL允许旧版重协商(未通过环境变量生效):
    [openssl_init]
    ssl_conf = ssl_sect
    
    [ssl_sect]
    system_default = system_default_sect
    
    [system_default_sect]
    Options = UnsafeLegacyRenegotiation
    

测试脚本

import socket
import ssl
import time

cipher = (':ECDHE-RSA-AES128-GCM-SHA256:DES-CBC3-SHA:AES256-SHA:AES128-SHA:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256:ECDHE-RSA-DES-CBC3:EDH-RSA-DES-CBC3:EECDH+AESGCM:EDH-RSA-DES-CBC3-SHA:EDH-AESGCM:AES256+EECDH:ECHDE-RSA-AES256-GCM-SHA384:ECHDE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECHDE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-A$:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK')
ssl._create_default_https_context = ssl._create_unverified_context

sslContext = ssl.create_default_context()
sslContext.check_hostname = False
sslContext.set_ciphers(cipher)
sslContext.verify_mode = ssl.CERT_NONE

clientSocket = socket.socket()
secureClientSocket = sslContext.wrap_socket(clientSocket, do_handshake_on_connect=False)

t1 = time.time()
retval = secureClientSocket.connect(("example.com", 443))
print("Time taken to establish the connection:%2.3f"%(time.time() - t1))

t3 = time.time()
secureClientSocket.do_handshake()
print("Time taken for SSL handshake:%2.3f"%(time.time() - t3))

serverCertificate = secureClientSocket.getpeercert()
print("Certificate obtained from the server:")
print(serverCertificate)

环境配置

openssl version
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)

python3 --version
Python 3.10.8

解决建议

  1. 修复加密套件字符串错误
    你的自定义加密套件字符串中存在截断:DHE-RSA-A$,这会导致OpenSSL无法解析合法的套件列表,直接引发握手失败。删除该错误片段,或直接使用默认加密套件测试(注释掉sslContext.set_ciphers(cipher))。

  2. 移除无效的猴子补丁
    ssl._create_default_https_context仅作用于urllib.request等高层库的默认上下文,你手动创建的sslContext不受其影响,删除该行避免干扰。

  3. 简化上下文配置
    先使用最简化的配置确认基础握手是否正常:

    sslContext = ssl.create_default_context()
    sslContext.check_hostname = False
    sslContext.verify_mode = ssl.CERT_NONE
    # 不要设置自定义cipher,先使用默认值
    
  4. 验证服务器SSL兼容性
    用OpenSSL命令行测试目标服务器的支持协议与套件:

    openssl s_client -connect example.com:443
    

    查看输出中的Cipher Suite和Protocol,确保客户端使用的协议/套件在服务器支持列表内。

  5. 正确加载OpenSSL配置(若需)
    若确实需要启用UnsafeLegacyRenegotiation,需将配置保存为文件(如openssl.cnf),然后通过环境变量指定:

    export OPENSSL_CONF=/path/to/openssl.cnf
    

    再运行Python脚本。

内容的提问来源于stack exchange,提问作者MC874

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:20:30