如何调整Python3.10 requests默认SSL设置解决sslv3握手失败问题
问题根因
Python 3.10 版本将内置SSL模块的默认安全等级提升至OpenSSL SECLEVEL=2,默认禁用了TLS 1.0/1.1协议,以及所有使用SHA1、3DES、RC4等弱算法的加密套件。你使用的本地Jazz RTC属于遗留系统,仅支持上述被禁用的旧协议/加密套件,因此握手失败。
注意verify=False参数仅用于关闭服务端证书合法性校验,不会修改TLS握手阶段的协议、加密套件协商规则,所以无法解决该问题。
可行解决方案
以下方案均不需要管理员权限、不需要降级Python版本、不需要修改服务端配置,全部配置仅在当前脚本内生效。
方案1:自定义SSL适配器对齐Python 3.9的TLS行为(推荐,直接可用)
通过自定义requests的HTTP适配器,手动构造兼容旧服务端的SSL上下文,完全对齐Python 3.9的默认TLS配置,只要3.9环境能正常跑通,该方案100%可用。
直接替换原有代码即可:
import ssl import requests import urllib3 from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager # 关闭verify=False触发的不安全请求警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class LegacyTLSAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): ssl_context = ssl.create_default_context() # 关闭证书校验,和原verify=False逻辑一致 ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE # 放开TLS版本限制,最低支持TLS1.0 ssl_context.minimum_version = ssl.TLSVersion.TLSv1 # 将OpenSSL安全等级设为0,放开所有弱加密套件限制 ssl_context.set_ciphers("DEFAULT@SECLEVEL=0") self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_context=ssl_context, **pool_kwargs ) if __name__ == '__main__': headers = {'Content-Type': 'application/x-www-form-urlencoded'} data = { 'j_username': username, 'j_password': password } # 初始化会话挂载自定义适配器 session = requests.Session() session.mount("https://", LegacyTLSAdapter()) resp = session.post(url, data=data, headers=headers, verify=False) result = resp.json() print(result)
方案2:精准匹配服务端配置(方案1无效时使用)
如果方案1仍然握手失败,说明服务端支持的协议/套件范围极窄,可以先通过本地openssl命令查询服务端支持的具体TLS版本和加密套件,普通用户权限即可执行:
- 测试TLS1.0支持:
openssl s_client -connect 你的服务端地址:端口 -tls1 - 测试TLS1.1支持:
openssl s_client -connect 你的服务端地址:端口 -tls1_1 - 测试TLS1.2支持:
openssl s_client -connect 你的服务端地址:端口 -tls1_2
执行后如果返回正常的证书链和Cipher is : xxx字段,就说明对应版本是服务端支持的,将代码中ssl_context.minimum_version和ssl_context.maximum_version都设为对应版本,再把返回的加密套件名称填入set_ciphers()即可。
举个例子,如果测试发现服务端仅支持TLS1.0、加密套件为AES128-SHA,则对应修改为:
ssl_context.minimum_version = ssl.TLSVersion.TLSv1 ssl_context.maximum_version = ssl.TLSVersion.TLSv1 ssl_context.set_ciphers("AES128-SHA")
注意事项
- 上述配置会降低TLS连接安全性,仅可用于对接内部可信的遗留服务,禁止在访问公网服务时使用
- 所有配置仅对当前脚本的requests请求生效,不会修改系统全局Python配置或OpenSSL配置,符合企业权限约束
内容的提问来源于stack exchange,提问作者Kliff Kast
相关产品推荐
相关产品推荐

