我在Python3.7中具有以下代码:
import urllib.request
import urllib.error
import ssl
import certifi
# Create the SSL context
# Was using cafile=certifi.where() before, but copied it inline. Read below
context = ssl.create_default_context(cafile='cacert.pem')
# Prepare the request
request = urllib.request.Request(some_url)
try:
connection = urllib.request.urlopen(request, context=context)
except urllib.error.URLError as e:
print(e)
我尝试了几种不同的some_url
,但是对于特定的https://hypelabs.io却遇到了问题。其他网址正在运行;我测试了https://facebook.com
,https://stackoverflow.com
等,它们都正常工作。对于hypelabs.io
,我得到了这个:
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)>
首先想到的是CA无法被系统识别,因此我需要首先安装CA证书。我在浏览器中检查了链,这就是我发现的:
但是,COMODO RSA Certification Authority
包含在我尝试过的所有捆绑文件中(按预期),也包含在钥匙串中(我使用的是MacOS High Sierra)。请注意,序列号匹配。
链中的第二个证书不在系统中。我知道根目录就足够了,但以防万一,在将CRT文件转换为PEM之后,我尝试下载并将其添加到捆绑文件中:
相同的结果。为什么此特定证书失败?我应该看什么?
答案 0 :(得分:1)
该站点配置错误,无法提供必要的中间证书。 SSLLabs report因此说:
This server's certificate chain is incomplete. Grade capped to B.
链中的第二个证书不在系统中。我知道根目录就足够了,但以防万一,在将CRT文件转换为PEM之后,我尝试下载并将其添加到捆绑文件中。
我的猜测是您在这里做错了。鉴于您的描述是正确的,我认为它与您实际所做的完全不符。
我用了与here相同的指纹来获取丢失的证书,并将其添加到根CA列表中(从/etc/ssl/certs/ca-certificates.crt
在Ubuntu上获取。此后,对该网站的访问有效没有任何问题。