Python - [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1091)
Posted
技术标签:
【中文标题】Python - [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1091)【英文标题】:Python - [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091) 【发布时间】:2021-11-25 21:12:54 【问题描述】:我有一个 Amazon linux 2 虚拟机,我正在从这个虚拟机发出一个 python 请求。为了提出请求,我使用的是自签名证书。
我已将自签名证书文件内容附加到文件“/etc/pki/tls/certs/ca-bundle.crt”中。
CURL 命令工作正常,但是当使用 python 的 requests 方法发出请求时,它会抛出以下错误。
错误:(由 SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1091)') 引起))
我尝试通过提供“MyAppcert.crt”和“ca_bundle.crt”文件的路径来对 Python 请求方法使用“验证”参数,但是这两种方法都失败了。
import requests
requests.get("https://<my-endpoint>:8888/", verify="/home/ec2-user/ssl_cert/MyAppcert.crt")
同样的用例在 Windows 服务器上运行良好。
任何帮助将不胜感激。
问候,
拉胡尔·库姆哈尔
【问题讨论】:
您是否安装了 certifi 模块?如果没有:做pip install certifi
不同的 TLS 堆栈验证证书的方式略有不同。确保自签名证书实际上启用了基本约束 CA:true(检查 openssl x509 -in file.pem -text
)
@MarijnKneppers:certifi 对自签名证书没有帮助。它仅适用于公共 CA 颁发的证书。
【参考方案1】:
您需要在发送套接字时伪造 SSL。 在你的代码中试试这个:
import ssl
# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
or
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
这两个对我来说都很好,例如 - https://twitter.com/bro_dev_/status/1447598426120720384?s=20 我今天运行了这段代码并且它工作正常。 从: https://github.com/webprice/python-twitter-examples/blob/f8ad6f69f423afdcbd83d89cc7e17e2f61d92ed4/bs4_SSL
【讨论】:
【参考方案2】:@SteffenUllrich 感谢您的回复。我使用“openssl x509 -in file.pem -text”验证了我的证书,发现缺少“keyUsage = Certificate Sign”。使用“keyUsage = Certificate Sign”创建新证书后,问题已解决。
【讨论】:
以上是关于Python - [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1091)的主要内容,如果未能解决你的问题,请参考以下文章
python https协议和InsecurePlatformWarning问题