urllib 2.x版本下dh key too small 等SSL类错误的解决方法
问题
当我们使用python的requests访问目标网站的时候,有时会遇到以下这种错误(以 https://dh-composite.badssl.com/ 为例)
requests.exceptions.SSLError: HTTPSConnectionPool(host='dh-composite.badssl.com', port=443): Max retries exceeded with url: /
(Caused by SSLError(SSLError(1, '[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:992)')))
这个时候我们在网上搜索解决办法往往是这种解决办法
import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'DEFAULT:@SECLEVEL=1'
# 或者
import urllib3
urllib3.util.ssl_.DEFAULT_CIPHERS = 'DEFAULT:@SECLEVEL=1'
但是在某些情况下我们发现是仍然没办法生效,或者直接提示没有DEFAULT_CIPHERS
这个属性的。
这是因为urllib3在2023年4月升级到了2.0.0版本,并且在新版本中废弃了DEFAULT_CIPHERS属性,所以我们需要另辟蹊径。
原因
具体原因可以看这个回答
简单来说DH_KEY_TOO_SMALL
的本质原因是目标网站的SECLEVEL设置为1,而这被认为是不安全的,所以访问会报错。解决办法就是强制将SECLEVEL设置为1或者0。在1.x的urllib3中,urllib3提供了DEFAULT_CIPHERS属性来自定义ssl相关的参数,但是在2.x版本中为了安全废弃了该属性。而由于requests实际上是调用urllib3请求网站,所以同样会出现这样的错误。
解决办法
在urllib3的issue中有位大佬提供了解决办法,也就是自定义HTTPAdapter的实例
以下是代码
import requests
import urllib3
# 自定义HTTPAdapter
class CustomSSLContextHTTPAdapter(requests.adapters.HTTPAdapter):
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = urllib3.poolmanager.PoolManager(
num_pools=connections, maxsize=maxsize,
block=block, ssl_context=self.ssl_context)
#自定义ssl_context
ctx = urllib3.util.create_urllib3_context()
ctx.load_default_certs()
ctx.set_ciphers("DEFAULT@SECLEVEL=0")
#替换原有的https的adapters
session = requests.session()
session.adapters.pop("https://", None)
session.mount("https://", CustomSSLContextHTTPAdapter(ssl_context=ctx))
response = requests.request(
method= "GET",
url='https://dh-composite.badssl.com/',
)
print(response.content)
这样就可以成功的请求目标网站了。同理对于其他ssl的错误也可以举一反三通过这样的方式更改ciphers的参数来进行解决。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~