如何无需修改代码强制Python requests模块使用更高版本TLS
强制
requests优先使用高版本TLS协议的解决方案 方法一:猴子补丁修改全局SSL上下文(无需修改第三方包)
在你调用第三方包的代码最前面添加以下代码,通过给requests全局会话挂载自定义适配器,强制禁用低版本TLS并兼容不安全密码套件:
import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager import ssl class TLSAdapter(HTTPAdapter): def init_poolmanager(self, *args, **kwargs): # 创建默认SSL上下文 ctx = ssl.create_default_context() # 降低安全级别以兼容服务器的不安全密码套件 ctx.set_ciphers('DEFAULT@SECLEVEL=1') # 禁用TLSv1和TLSv1.1,强制使用更高版本协议 ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 kwargs['ssl_context'] = ctx return super().init_poolmanager(*args, **kwargs) # 给所有HTTPS请求挂载适配器 requests.session().mount('https://', TLSAdapter())
这段代码会覆盖requests默认的SSL配置,确保所有请求都优先使用TLSv1.2及以上版本,同时适配服务器的不安全密码套件。
方法二:使用环境变量控制(依赖urllib3版本)
如果你的环境中urllib3版本≥1.26.0,可以通过设置环境变量直接禁用低版本TLS:
# 禁用TLSv1 export URLLIB3_SSL_NO_TLSv1=1 # 禁用TLSv1.1 export URLLIB3_SSL_NO_TLSv1_1=1
设置完成后再运行你的Python脚本,urllib3会自动过滤掉低版本协议,让requests只能协商TLSv1.2及以上版本。
关于TLS协商顺序的疑问解答
正常TLS协商逻辑是:客户端发送自身支持的协议版本列表(按优先级从高到低排列),服务器选择双方都支持的最高版本。你遇到的“从低版本开始尝试”的异常情况,可能由以下原因导致:
- 第三方包隐式修改了
requests的SSL上下文,将低版本协议设为最高优先级 - 目标API服务器的TLS实现存在缺陷,不遵循标准协商逻辑,仅接受客户端发送的第一个协议版本
- 你使用的Python/urllib3/OpenSSL版本过旧,默认协议顺序存在反向排列的问题
内容的提问来源于stack exchange,提问作者Appleoddity
相关产品推荐
相关产品推荐

