Python证书验证失败:无法获取本地颁发者证书

时间:2020-10-10 20:33:47

标签: python-3.x urllib2 client-certificates

我是一名新手程序员,所以请原谅我的错误。我已经编写了以下代码,以验证网站列表仍处于活动状态,并且我的所有工作都基于此问题陈述。

该脚本能够检查大多数站点,但因https://precisionit.net/

而遇到以下错误
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)>

上面的URL在Firefox和Chrome中可以正常打开,但无法在Python代码中打开。我已更新证书并按照许多人的建议在我的代码中使用了它,但错误不会消失。

我正在使用Conda Python Env,并且还执行了以下命令

conda install -c conda-forge certifi

有多篇文章建议运行不适用于Conda Python的“ Install Certificates.command”,因此我下载了Python 3.9安装程序并执行了“ Install Certificates.command”,并使用Python 3.9执行了脚本,但没有运气。我认为问题在于,即使使用最新版本的certifi,站点证书也未通过验证。尽管certifi page表示该列表基于Mozilla的根证书,但我猜它不是精确的副本,这就是Firefox能够打开该网站的原因。不知道我的理解是否有意义,并且会很乐意得到纠正。

在下面粘贴我的脚本。敬请告知,我不确定还需要做什么来解决该问题。

import urllib.request
import sys
import certifi
import ssl

def checkURL(url):
    try: 
        
        hdr = { 'User-Agent' : 'Mozilla/79.0 (Windows NT 6.1; Win64; x64)' }
        req=urllib.request.Request(url,headers=hdr)
        r = urllib.request.urlopen(req,timeout=100,context=ssl.create_default_context(cafile=certifi.where()))
        
    except Exception as e:
        #print(r.read())
        print('Failed Connecting to Website')
        print(e)
        return(1)

    print(r.status)
    finalurl = r.geturl()
    if r.status==200:
        print(finalurl)
        return(0)
    else:
        print("Website Not Found")
        return(2)

checkURL('https://precisionit.net/')

1 个答案:

答案 0 :(得分:0)

我遇到了类似的问题,我就是这样解决的。

首先,检查站点证书的颁发者是谁。您可以通过多种方式执行此操作(检查浏览器,使用 openssl ... 进行连接)。

最简单的方法可能是前往 https://www.digicert.com/help/ 并搜索 https://precisionit.net

enter image description here

您可能错过了Sectigo RSA Domain Validation Secure Server CA。只需访问他们的网站 (https://support.sectigo.com/Com_KnowledgeDetailPage?Id=kA01N000000rfBO) 并下载即可。

然后使用 cacert.pem 获取保存您的证书的 certifi.where() 文件的位置,并将您下载的证书的内容添加到所述文件中。

证书应该是形式

-----BEGIN CERTIFICATE-----  
... some base64 encoded stuff ...  
-----END CERTIFICATE-----