Python 3.10报[SSL:SSLV3_ALERT_HANDSHAKE_FAILURE] (_ssl.c:997)问题求助
解决Python 3.10中SSL握手失败问题
问题原因
Python 3.10大幅提高了TLS默认安全级别,不仅加密套件要求更严格,还默认禁用了老旧的TLS 1.0/1.1版本。即使修改DEFAULT_CIPHERS为ALL:@SECLEVEL=1,也可能因为未开启服务器支持的旧TLS版本,或者requests未正确应用自定义SSL配置导致问题。
解决方案
1. 自定义SSL适配器,指定支持的TLS版本
通过创建自定义HTTP适配器,精确控制SSL上下文,包括加密套件和允许的TLS版本:
import requests import ssl from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager class TLSAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): # 创建SSL上下文 ctx = ssl.create_default_context() # 设置加密套件和安全级别 ctx.set_ciphers('ALL:@SECLEVEL=1') # 启用TLS 1.0和1.1(根据服务器实际支持情况调整) ctx.options &= ~ssl.OP_NO_TLSv1 ctx.options &= ~ssl.OP_NO_TLSv1_1 # 初始化连接池管理器 self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx ) # 使用Session挂载适配器 session = requests.Session() session.mount('https://', TLSAdapter()) # 注意:GET请求用json参数传递数据(对应application/json头) headers = {'Content-Type':'application/json'} data = { 'selct1': sel, 'selct2': der } res = session.get(url, json=data, headers=headers, verify=False)
提示:如果服务器仅支持TLS 1.2,可移除
ctx.options &= ~ssl.OP_NO_TLSv1和ctx.options &= ~ssl.OP_NO_TLSv1_1两行,避免不必要的安全风险。
2. 检查服务器支持的TLS版本
用openssl命令确认服务器兼容的TLS版本:
# 检查TLS 1.0支持 openssl s_client -connect example.com:443 -tls1 # 检查TLS 1.1支持 openssl s_client -connect example.com:443 -tls1_1 # 检查TLS 1.2支持 openssl s_client -connect example.com:443 -tls1_2
根据输出结果调整适配器中启用的TLS版本。
3. 更新依赖包
旧版本的requests或urllib3可能与Python 3.10的SSL逻辑不兼容,更新到最新版:
pip install --upgrade requests urllib3
为什么之前的修改无效?
直接修改requests.package.urllib3.util.ssl_.DEFAULT_CIPHERS仅全局修改加密套件,但requests在创建SSL上下文时,会默认应用系统级的TLS版本限制(如禁用1.0/1.1),自定义适配器能直接覆盖这些默认限制。
内容的提问来源于stack exchange,提问作者Shastransu Suprabh
相关产品推荐
相关产品推荐

