如果您使用请求版本 2.12.0+,Configuring TLS With Requests 上有一篇博文,其中描述了允许您配置 SSLContext 的新功能(请注意,这篇博文是在 OP 提出问题后编写的) :
Requests v2.12.0 中添加的功能是 urllib3 现在接受一个
ConnectionPool 对象的构造函数中的 SSLContext 对象。这
SSLContext 将用作底层 TLS 的工厂
连接,因此应用于它的所有设置也将应用于
那些低级的连接。
最好的方法是使用 SSLContext 工厂函数
requests.packages.urllib3.util.ssl_.create_urllib3_context。这是
类似于 Python 的 ssl.create_default_context 函数,但适用
Requests 和 urllib3 的更严格的默认 TLS 配置
两者都使用。这个函数将返回一个 SSLContext 对象,然后可以
应用了进一步的配置。最重要的是,该功能还
需要一些参数来允许覆盖默认配置。
要提供新的 SSLContext 对象,您需要编写一个
适用于给定主机的 TransportAdapter。
以下示例代码作为示例,说明如何使用此方法在请求中重新启用 3DES。
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
# This is the 2.11 Requests cipher string, containing 3DES.
CIPHERS = (
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
'!eNULL:!MD5'
)
class DESAdapter(HTTPAdapter):
"""
A TransportAdapter that re-enables 3DES support in Requests.
"""
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
s = requests.Session()
s.mount('https://some-3des-only-host.com', DESAdapter())
r = s.get('https://some-3des-only-host.com/some-path')
还有一个 hack 可能,您可以在 github pages for the requests module 或 https://stackoverflow.com/a/32651967/2364215 上阅读它,但它会修改底层库代码,我不推荐它(请求模块的作者也不推荐,因为您将在该页面上找到)。另一方面,如果您使用的是较旧的请求包并且无法升级,那么它可能是您的最佳选择。相当于覆盖了 urllib3 模块的DEFAULT_CIPHERS:
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA'
如果您有其他代码在修改后将使用 requests 模块,但不需要修改,您可能需要将 DEFAULT_CIPHERS 恢复为之前的值。