如何让Python requests支持指定弱TLS加密套件?
让Python requests库适配指定加密套件的解决方法
问题概述
目标设备仅支持以下RSA类AES加密套件,使用requests发起HTTPS请求时遭遇SSL握手失败:
Max retries exceeded with url: /jaws/monitor/units (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)')))
需支持的加密套件:
- TLS_RSA_WITH_AES_256_GCM_SHA384
- TLS_RSA_WITH_AES_256_CBC_SHA256
- TLS_RSA_WITH_AES_256_CBC_SHA
- TLS_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_128_CBC_SHA256
- TLS_RSA_WITH_AES_128_CBC_SHA
实现步骤
requests依赖urllib3和OpenSSL,需通过自定义SSL上下文强制指定加密套件,具体如下:
1. 自定义HTTP适配器
创建继承自HTTPAdapter的适配器类,在初始化连接池时配置指定的加密套件和TLS版本。
2. 绑定适配器到requests会话
将自定义适配器挂载到requests会话,让所有HTTPS请求使用该配置。
完整示例代码
import ssl import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager class CipherSpecAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): # 用冒号分隔指定的加密套件 target_ciphers = ( 'TLS_RSA_WITH_AES_256_GCM_SHA384:' 'TLS_RSA_WITH_AES_256_CBC_SHA256:' 'TLS_RSA_WITH_AES_256_CBC_SHA:' 'TLS_RSA_WITH_AES_128_GCM_SHA256:' 'TLS_RSA_WITH_AES_128_CBC_SHA256:' 'TLS_RSA_WITH_AES_128_CBC_SHA' ) # 创建SSL上下文并设置加密套件 ssl_context = ssl.create_default_context() ssl_context.set_ciphers(target_ciphers) # 若目标设备仅支持旧版TLS(如TLS 1.0/1.1),解除对应限制 ssl_context.options &= ~ssl.OP_NO_TLSv1_0 ssl_context.options &= ~ssl.OP_NO_TLSv1_1 # 初始化连接池 self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_context=ssl_context ) # 初始化会话并挂载适配器 session = requests.Session() session.mount('https://', CipherSpecAdapter()) # 发起请求 try: res = session.get('https://你的目标设备地址/jaws/monitor/units') res.raise_for_status() print(res.content.decode()) except requests.exceptions.SSLError as ssl_err: print(f"SSL握手失败: {ssl_err}") except requests.exceptions.RequestException as req_err: print(f"请求出错: {req_err}")
额外说明
- 若目标设备使用自签名证书,需在SSL上下文添加以下配置(仅在可信环境中使用,会降低安全级别):
ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE - 确保本地OpenSSL版本支持上述加密套件,可通过
openssl ciphers -v命令查看已支持的套件列表。 - 若仍失败,可尝试将
ssl_context的ssl_version指定为具体版本,比如ssl.PROTOCOL_TLSv1。
内容的提问来源于stack exchange,提问作者Craig Smith
相关产品推荐
相关产品推荐

