Python requests返回错误:CA证书的Basic Constraints未标记为关键
我是处在企业网内,需要使用自签名证书,当我对我的端点发送POST请求时,会得到以下错误
response = requests.post(self.api, headers=headers, cookies=cookies, json=silence, verify=self.certificate, timeout=(10, 10))
(Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical (_ssl.c:1077)')))
据我所理解,这是因为我从浏览器下载的根证书,我没有权限修改它,但它并没有被标记为关键证书
X509v3 Basic Constraints:
CA:TRUE, pathlen:2
我有一个较旧的脚本,使用相同的请求和cert.pem就能工作
较旧的脚本:
Python 3.14.0
------------------ -----------
attrs 25.3.0
certifi 2025.1.31
cffi 1.17.1
charset-normalizer 3.4.1
h11 0.14.0
idna 3.10
outcome 1.3.0.post0
pip 25.2
pycparser 2.22
PySocks 1.7.1
requests 2.32.3
selenium 4.30.0
sniffio 1.3.1
sortedcontainers 2.4.0
trio 0.29.0
trio-websocket 0.12.2
typing_extensions 4.13.0
urllib3 2.3.0
websocket-client 1.8.0
wsproto 1.2.0
response = requests.post(self.cluster_api, headers=headers, cookies=cookies, json=request_data, verify=self.certificate, timeout=(10, 10)) #request
新脚本:
Python 3.14.0
Package Version
------------------ -----------
attrs 26.1.0
certifi 2026.4.22
charset-normalizer 3.4.7
h11 0.16.0
idna 3.13
outcome 1.3.0.post0
pip 25.2
PySocks 1.7.1
requests 2.33.1
selenium 4.43.0
sniffio 1.3.1
sortedcontainers 2.4.0
trio 0.33.0
trio-websocket 0.12.2
typing_extensions 4.15.0
urllib3 2.6.3
websocket-client 1.9.0
wsproto 1.3.2
不过我不明白为什么这个请求在前一个版本会工作,是否与requests的版本有关?
有没有办法在不进行 verify=False 的情况下变通解决?
解决方案
requests 2.32.3使用一个SSL上下文来创建 create_urllib3_context - 参见adapters.py中的 第76行 和 第96行。在urllib 2.3.0 这个函数 只是创建了一个新的 ssl.SSLContext,但并未设置任何特殊的验证参数。
在2.33.1版本中,requests不再创建自己的SSL上下文,因此隐式地依赖于 ssl.create_default_context。自Python 3.13.0起,这里 添加了验证参数,特别是VERIFY_X509_STRICT。这个参数会导致你看到的错误信息。
由于在requests 2.32.3和 urllib3 2.3.0时没有使用此验证选项,因此对这两个旧模块中的损坏证书不会报错。更新版本的urllib3也新增了这个验证参数。
最好的修复办法是替换掉显然损坏的证书。它可能来自 ZScaler的一个漏洞,应当得到修复。
也可能存在一种变通方法,在创建SSL上下文时显式禁用这个选项。AI实际上可以帮助编写相关代码片段,但出于站点政策,这里不展示结果。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。