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 365ca_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
相关产品推荐
相关产品推荐

