You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

urllib3自签名证书验证失败求助(非禁用验证方案)

问题描述

尝试连接非公开第三方系统,双方使用自签名证书。持有第三方提供的证书、私钥及验证证书,curl调用可正常工作:

curl https://third_party_url.com/hello -iv --cert ./cert.cert --cacert ./verify.cert --key ./key.key

但通过Python 3的urllib3 PoolManager实现时,出现SSL验证失败错误:

client = urllib3.PoolManager(
    cert_file = "./cert.cert",
    key_file="./key.key",
    ca_certs="./verify.cert",
    cert_reqs="CERT_REQUIRED"
)
resp = client.request("GET", "https://third_party_url.com/hello")

报错信息:

Exception has occurred: SSLError
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)

禁用证书验证不可行,需有效解决思路。

补充信息:

  • 不带-cacert参数执行curl时,同样出现相同错误,疑似urllib3未正确加载指定的验证证书。
  • 执行openssl x509 -in verify.cert -text查看验证证书,发现其未设置basic constraints为CA:true。

解决思路

1. 修正验证证书的CA属性(优先推荐)

Python依赖的SSL栈会拒绝将未设置basicConstraints=CA:true的证书作为信任锚,这是核心问题:

  • 联系第三方,要求提供带有basicConstraints=CA:true的CA证书。
  • 若需自行处理,可通过OpenSSL重新签署证书添加CA属性:
    # 创建CA配置文件ca.conf
    cat > ca.conf << EOF
    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_ca
    [req_distinguished_name]
    [v3_ca]
    basicConstraints = CA:true
    EOF
    
    # 重新生成带CA属性的验证证书
    openssl x509 -in verify.cert -out verify_ca.cert -signkey verify.key -extfile ca.conf -days 365
    
    修改代码中的ca_certs参数为新生成的verify_ca.cert即可。

2. 手动构建SSL上下文(无法修改证书时使用)

如果无法获取带CA属性的证书,可手动创建SSL上下文,强制将目标证书加入信任链:

import ssl
import urllib3

# 初始化SSL上下文
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
# 加载客户端证书和私钥
context.load_cert_chain(certfile="./cert.cert", keyfile="./key.key")
# 加载验证证书(忽略CA属性限制)
context.load_verify_locations(cafile="./verify.cert")
# 保持证书验证模式,仅关闭不必要的检查(若证书CN与域名匹配,可保留check_hostname=True)
context.check_hostname = False
context.verify_mode = ssl.CERT_REQUIRED

# 使用自定义上下文创建PoolManager
client = urllib3.PoolManager(ssl_context=context)
resp = client.request("GET", "https://third_party_url.com/hello")

注意:check_hostname=False仅在第三方证书的域名与请求域名匹配时使用,否则会增加中间人攻击风险。

3. 检查证书文件格式

确保所有证书都是PEM格式:

  • 执行openssl x509 -in ./cert.cert -text -noout验证格式有效性。
  • 若为DER格式,转换为PEM:
    openssl x509 -inform der -in cert.der -out cert.cert
    

内容的提问来源于stack exchange,提问作者FreakShow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:00:50