ChatGPT解决这个技术问题 Extra ChatGPT

urllib 和“SSL:CERTIFICATE_VERIFY_FAILED”错误

我收到以下错误:

Exception in thread Thread-3:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in        __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in  run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Matthew/Desktop/Skypebot 2.0/bot.py", line 271, in process
info = urllib2.urlopen(req).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>

这是导致此错误的代码:

if input.startswith("!web"):
    input = input.replace("!web ", "")      
    url = "https://domainsearch.p.mashape.com/index.php?name=" + input
    req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXX' })
    info = urllib2.urlopen(req).read()
    Message.Chat.SendMessage ("" + info)

我使用的 API 要求我使用 HTTPS。我怎样才能让它绕过验证?

URL 没有问题,可以通过常见的可信证书成功验证。所以你最好不要试图绕过证书验证,而是修复它。你使用的是哪个版本的python?
这可能与 stackoverflow.com/a/27826829/3081018 有关。服务器使用具有多个信任路径的相同类型的证书链。在那里查看您可能需要使用哪个 cafile 进行验证。
Python 3.5 升级到 yosemite 后也会出现此错误
这说明了情况。 access.redhat.com/articles/2039753
“我怎样才能让它绕过验证?”是错误的问题。您可能应该询问如何验证域提供的证书。

0
0 _

这不是针对您的特定问题的解决方案,但我将其放在这里是因为该线程是“SSL:CERTIFICATE_VERIFY_FAILED”的最高 Google 结果,它使我大吃一惊。

如果您在 OSX 上安装了 Python 3.6 并在尝试连接到 https:// 站点时收到“SSL:CERTIFICATE_VERIFY_FAILED”错误,这可能是因为 OSX 上的 Python 3.6 根本没有证书,并且无法验证任何 SSL连接。这是对 OSX 上 3.6 的更改,需要安装后步骤,即安装 certifi 证书包。这记录在文件 ReadMe.rtf 中,您可以在 /Applications/Python\ 3.6/ReadMe.rtf 中找到该文件(另请参阅文件 Conclusion.rtf 和生成 macOS 安装程序的脚本 build-installer.py)。

自述文件将让您在 /Applications/Python\ 3.6/Install\ Certificates.command(其源为 install_certificates.command)处运行安装后脚本,其中:

首先安装 Python 包 certifi,然后

然后创建从 OpenSSL 证书文件到包 certifi 安装的证书文件的符号链接。

发行说明有更多信息:https://www.python.org/downloads/release/python-360/

在较新版本的 Python 上,有更多关于此的文档:

https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/ReadMe.rtf#L22-L34

https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Conclusion.rtf#L15-L19

https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Welcome.rtf#L23-L25

https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/install_certificates.command

https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/README.rst

https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/build-installer.py#L239-L246


直接运行 /Applications/Python\ 3.6/Install\ Certificates.command 解决我在 OSX 上的问题。谢谢。
我正在使用 OS X El Capitan 10.11.6、Python 3.6.0,这个解决方案运行良好。
我正在使用 macOS Sierra 10.12.5、Python 3.6.1,这个解决方案运行良好。
这为我修复了它/Applications/Python\ 3.7/Install\ Certificates.command,直接在 terminal 中运行它!谢谢@CraigGlennie & @muyong 我感谢 out-of-the-box-thinking 把它放在这里!
macOS Mojave 上的 Python 3.7:它在这里不起作用。我已卸载/重新安装/运行安装证书、重新启动等。对我不起作用
A
Asclepius

如果您只是想绕过验证,可以创建一个新的 SSLContext。默认情况下,新创建的上下文使用 CERT_NONE

如第 17.3.7.2.1 节所述,请注意这一点

直接调用 SSLContext 构造函数时,CERT_NONE 是默认值。由于它不对其他对等方进行身份验证,因此它可能是不安全的,尤其是在客户端模式下,在大多数情况下您希望确保正在与之交谈的服务器的真实性。因此,在客户端模式下,强烈建议使用 CERT_REQUIRED。

但是,如果您只是出于其他原因希望它现在可以工作,您可以执行以下操作,您还必须import ssl

input = input.replace("!web ", "")      
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' })
gcontext = ssl.SSLContext()  # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)

这应该可以解决您的问题,但您并没有真正解决任何问题,但是您不会看到 [SSL: CERTIFICATE_VERIFY_FAILED],因为您现在没有验证证书!

此外,如果您想进一步了解为什么会出现这些问题,请查看 PEP 476

此 PEP 建议在默认情况下启用 X509 证书签名的验证,以及 Python 的 HTTP 客户端的主机名验证,但需要在每次调用的基础上选择退出。此更改将应用于 Python 2.7、Python 3.4 和 Python 3.5。

有一个建议退出,这与我上面的建议没有什么不同:

import ssl

# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)

它还通过 monkeypatching 提供了一个 强烈建议 选项,这在 python 中并不常见:

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

它使用创建未验证上下文的函数覆盖用于创建上下文的默认函数。

请注意,如 PEP 中所述:

本指南主要针对希望采用较新版本的 Python 以在尚不支持 HTTPS 连接上的证书验证的旧环境中实现此 PEP 的系统管理员。例如,管理员可以通过将上面的 monkeypatch 添加到他们的 Python 标准操作环境中的 sitecustomize.py 来选择退出。应用程序和库不应该在整个过程中进行这种更改(除非可能是为了响应系统管理员控制的配置设置)。

如果您想阅读一篇关于为什么不验证证书在软件中不好的论文 you can find it here


因此,如果此错误使我无法使用 setup.py upload,我该如何解决?
ssl._create_default_https_context = ssl._create_unverified_context 这对我有用,正如 Noelkd 在最后提到的那样。由于我们是 HP 打印机的 Intranet 站点……纯粹用于抓取……我们使用这种方法没有问题。
您的第一种方法是最不可取的方法 - 绕过验证。为什么实际验证证书的不是第一个列出的?
如果您的 openSSL 版本过时,也会发生这种情况。所以对我来说,有效的是更新到最新版本的 certifi 并更新盒子上的 openssl。
context 是我需要的
J
Jean-François Fabre

扩展 Craig Glennie 的回答:

在 MacOs Sierra 上的 Python 3.6.1 中

在 bash 终端中输入这个可以解决问题:

pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command

如果权限被拒绝,请尝试 sudo /Applications/Python\ 3.6/Install\ Certificates.command
这实际上并不能解决 Python 3.6 上的问题。 -1
如果使用命令行让您感到害怕(如果您在这里,可能不会,但是嘿),您还可以找到 Python 在安装时创建的 Applications 文件夹(或其他操作系统上的等效文件夹),然后双击打开脚本。文件夹的具体名称取决于您安装的 Python 版本。
像 Python 3.7.3 的魅力一样工作。谢谢你。
谢谢。我从字面上搜索了 100 种解决方案,而您的解决方案有效。
B
Bruno Gabuzomeu

在 Windows 上,Python 不查看系统证书,它使用位于 ?\lib\site-packages\certifi\cacert.pem 的自己的证书。

您的问题的解决方案:

将域验证证书下载为 *.crt 或 *pem 文件在编辑器中打开文件并将其内容复制到剪贴板找到您的 cacert.pem 位置: from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH) 编辑 cacert.pem 文件并将您的域验证证书粘贴到文件末尾。保存文件并享受请求!


lib\site-packages\certifi\cacert.pem 在 Python 2.7.10 中不存在。问题是关于 urllib2 而不是 requests
迄今为止最好的解决方案,twitter API 使用不在我的 python 的 cacert.pem 文件中的 DigiCert 证书。我在那里添加了,瞧!
在Debian上工作。作为记录,我系统上的文件路径是:/usr/local/lib/python2.7/dist-packages/certifi-2015.09.06.2-py2.7.egg/certifi/cacert.pem。谢谢!
不幸的是,python 请求不使用任何操作系统的 CA 信任库。 github.com/requests/requests/issues/2966。您必须设置 REQUESTS_CA_BUNDLE github.com/bloomreach/s4cmd/issues/111#issuecomment-406839514
可在 Windows 10、Python 3.6 上使用 Google 和 Twitter API 以及一般的请求模块。
S
Saim Ehsan

尽管我在 Python 3.4、3.5 和 3.6 中使用了 urllib.request.urlopen,但我遇到了类似的问题。 (这是 Python 3 中 urllib2 的一部分,根据 Python 2 的 urllib2 documentation page 开头的注释。)

我的解决方案是 pip install certifi 安装 certifi,它具有:

... 精心策划的根证书集合,用于验证 SSL 证书的可信度,同时验证 TLS 主机的身份。

然后,在我之前刚刚拥有的代码中:

import urllib.request as urlrq

resp = urlrq.urlopen('https://example.com/bar/baz.html')

我将其修改为:

import urllib.request as urlrq
import certifi

resp = urlrq.urlopen('https://example.com/bar/baz.html', cafile=certifi.where())

如果我正确阅读了 urllib2.urlopen documentation,它还有一个 cafile 参数。因此,urllib2.urlopen([...], certifi.where()) 也可能适用于 Python 2.7。

更新 (2020-01-01): 从 Python 3.6 开始,the cafile argument to urlopen has been deprecated,应该指定 context 参数。我发现以下在 3.5 到 3.8 上同样适用:

import urllib.request as urlrq
import certifi
import ssl

resp = urlrq.urlopen('https://example.com/bar/baz.html', context=ssl.create_default_context(cafile=certifi.where()))

load_verify_locations 改变 SSLContext 实例并返回 None。您应该改用 context=ssl.create_default_context(cafile=certifi.where())。有关详细信息,请参阅 ssl docs
@ostrokach 嗯,我尝试过类似的方法,但我一定使用了错误的 ssl 函数。见编辑;好?
这就是答案。谢谢。
@hBy2Py 我想这可能会解决我的问题askubuntu.com/questions/1401379/certificate-verify-failed-error 问题:什么是 baz.html?您的 Django 应用程序的模板 URL?导入是否进入views.py?
要在这里回答您的具体问题,@BlueDogRanch:1) https://.../baz.html 只是一个假网站地址,用于演示语法。 2) 导入需要进入调用 urlopen()(或任何资源打开器)函数的任何模块,并且指向 certifi 证书的新 SSL 上下文需要作为 context 关键字传递到打开器争论)。
C
Claude COULOMBE

我的 Mac OS X 解决方案:

1) 使用从官方 Python 语言网站下载的本机应用 Python 安装程序升级到 Python 3.6.5 https://www.python.org/downloads/

我发现这个安装程序在更新新 Python 的链接和符号链接方面比自制软件要好得多。

2) 使用刷新的 Python 3.6 目录中的“./Install Certificates.command”安装新证书

> cd "/Applications/Python 3.6/"
> sudo "./Install Certificates.command"

在 Mac OS X 中像魅力一样工作。
用一位老同事的话说……“你是冠军男人”
尝试了其他几种解决方案:这适用于 10.14 Mojave
C
Chris Halcrow

您可以尝试将其添加到您的环境变量中:

PYTHONHTTPSVERIFY=0 

请注意,这将禁用所有 HTTPS 验证,因此有点像大锤方法,但是如果不需要验证,它可能是一个有效的解决方案。


我怀疑为所有 python 禁用所有 HTTP 验证对于处理验证中的一个错误有点过分。在很多情况下,默认情况下可能需要验证。
在 python 2.7.13 上的 Windows Server 2016 上为我工作。我通常没有在 Windows 服务器上安装 python,但需要它用于将 Nexus 1000v 迁移到 VDS 的 vCenter 升级,这只是暂时解决了自签名 vCenter 证书的问题(将使用 VMCA 和有效证书升级环境)。我没有运气通过编辑 python 请求包中的 cacert.pem 来接受证书
另外,我在运行脚本之前直接在命令行窗口中设置了变量,所以它不会禁用像@someone-or-other 那样害怕的所有检查,我也不建议这样做。
这非常适合我的用例:测试。我永远不会在生产环境中这样做,但对于运行与 SSL 无关的测试,这是一个很好的选择。
谢谢,这个解决方案为我做了: import os os.environ["PYTHONHTTPSVERIFY"] = "0"
r
ritiek

我在我的一台 Linux 机器上遇到了类似的问题。生成新证书并导出指向证书目录的环境变量为我修复了它:

$ sudo update-ca-certificates --fresh
$ export SSL_CERT_DIR=/etc/ssl/certs

这有助于解决 Ubuntu 机器上的问题
P
Prostak
import requests
requests.packages.urllib3.disable_warnings()

import ssl

try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    # Legacy Python that doesn't verify HTTPS certificates by default
    pass
else:
    # Handle target environment that doesn't support HTTPS verification
    ssl._create_default_https_context = _create_unverified_https_context

取自这里https://gist.github.com/michaelrice/a6794a017e349fc65d01


在 Jenkins 环境、个人环境中测试了这个解决方案,这行得通!
这是非常不安全的,因为它绕过了所有证书验证,使用风险自负,并且出于对任何人的热爱,请勿在生产代码中使用它。
谢谢。最后它奏效了。在 Mac OS 上的 /Applications 下不需要安装 Python 3.6。这应该是公认的答案。
你永远不应该做这样的猴子补丁。这是极其危险的,会影响代码的所有下游使用。
j
jwpfox

就像我在评论中写的那样,这个问题可能与 this SO answer 有关。

简而言之:有多种方法可以验证证书。 OpenSSL 使用的验证与您系统上的受信任根证书不兼容。 Python 使用 OpenSSL。

您可以尝试获取 Verisign Class 3 Public Primary Certification Authority 的缺失证书,然后根据 Python documentation 使用 cafile 选项:

urllib2.urlopen(req, cafile="verisign.pem")

你能帮我解决这个在 python 和 ssl 验证中的相关问题吗?link
v
veganaiZe
$ cd $HOME
$ wget --quiet https://curl.haxx.se/ca/cacert.pem
$ export SSL_CERT_FILE=$HOME/cacert.pem

来源:https://access.redhat.com/articles/2039753


这似乎太简单了,我在最初的搜索中通过了这个。我现在在踢自己。在 Ubuntu 上,为什么 Python 的 Certifi 使用单独的捆绑证书包而不是首先默认使用系统证书包非常令人困惑。谢谢你拯救了我的一周。
测试也可以在 Windows 上工作,将导出更改为设置。
当您在 Mac 中使用 flask-appbuilder 运行 flask run create-app 时遇到 SSL 证书错误时,这将为您提供帮助,而无需运行 sudo
嗨@veganaiZe 为什么 haxx.se 证书有效?这是我应该尝试的askubuntu.com/questions/1401379/certificate-verify-failed-error
嗨@BlueDogRanch,不确定你的意思;也许这个链接有帮助? curl.se/docs/caextract.html
L
Leo

Anaconda 的解决方案

我的设置是 MacOS 上带有代理的 Anaconda Python 3.7。路径不同。

这是您获得正确证书路径的方式:

import ssl
ssl.get_default_verify_paths()

在我的系统上产生

Out[35]: DefaultVerifyPaths(cafile='/miniconda3/ssl/cert.pem', capath=None,
 openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/miniconda3/ssl/cert.pem',
 openssl_capath_env='SSL_CERT_DIR', openssl_capath='/miniconda3/ssl/certs')

一旦您知道证书的去向,您就可以将代理使用的证书连接到该文件的末尾。

我已经设置了 conda 来使用我的代理,通过运行:

conda config --set ssl_verify <pathToYourFile>.crt

如果您不记得您的证书在哪里,您可以在 ~/.condarc 中找到它:

ssl_verify: <pathToYourFile>.crt

现在连接该文件到 /miniconda3/ssl/cert.pem 的末尾并且请求应该可以工作,特别是 sklearn.datasets 和类似的工具应该可以工作。

进一步的注意事项

其他解决方案不起作用,因为 Anaconda 设置略有不同:

路径 Applications/Python\ 3.X 根本不存在。

以下命令提供的路径是错误的路径

from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH

你是我的英雄!
c
corwin.amber

我需要添加另一个答案,因为就像 Craig Glennie 一样,由于网络上很多帖子都提到了这个问题,我进行了一次疯狂的追逐。

我正在使用 MacPorts,我最初认为是 Python 问题实际上是 MacPorts 问题:它不会在安装 openssl 时安装根证书。解决方案是 port install curl-ca-bundle,如 this blog post 中所述。


j
jww

我很惊讶所有这些指令都没有解决我的问题。尽管如此,诊断结果是正确的(顺便说一句,我使用的是 Mac 和 Python3.6.1)。因此,总结正确的部分:

在 Mac 上,Apple 正在放弃 OpenSSL

Python 现在使用它自己的一组 CA 根证书

二进制 Python 安装提供了一个脚本来安装 Python 需要的 CA Root 证书(“/Applications/Python 3.6/Install Certificates.command”)

阅读“/Applications/Python 3.6/ReadMe.rtf”了解详情

对我来说,脚本不起作用,所有那些 certifi 和 openssl 安装也无法修复。也许是因为我有多个 python 2 和 3 安装,以及许多 virtualenv。最后,我需要手动修复它。

pip install certifi   # for your virtualenv
mkdir -p /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl
cp -a <your virtualenv>/site-package/certifi/cacert.pem \
  /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/cert.pem

如果这仍然让你失败。然后重新/安装 OpenSSL。

port install openssl

G
Ganesh Chowdhary Sadanala

我在 here 上找到了这个

我找到了这个解决方案,在源文件的开头插入这段代码:

import ssl

try:
   _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    # Legacy Python that doesn't verify HTTPS certificates by default
    pass
else:
    # Handle target environment that doesn't support HTTPS verification
    ssl._create_default_https_context = _create_unverified_https_context

此代码使验证撤消,因此不验证 ssl 认证。


看这个视频它帮助我理解了什么是 ssl。视频网址:youtu.be/dsuVPxuU_hc
c
caot

Python 2.7.12(默认,2016 年 7 月 29 日,15:26:22)修复了上述问题。此信息可能对其他人有所帮助。


我在 mac 上的 2.7.12 上遇到它,使用 urllib2 库,使用 requets 库似乎很好
@marcadian 安装和使用 certifi,这显然是 requestsfixed the problem for me on Python 3.4 to 3.6 持有的证书的刮擦。
在将 Python 更新到 2.7.17 后,我使用的是 Python 2.7,非常感谢。
W
WebDev

SSL: CERTIFICATE_VERIFY_FAILED 错误也可能发生,因为 Linux 上的 ca-certificates 包中缺少中间证书。例如,在我的例子中,中间证书“DigiCert SHA2 Secure Server CA”在 ca-certificates 包中丢失,即使 Firefox 浏览器包含它。您可以通过直接在导致此错误的 URL 上运行 wget 命令来找出缺少哪个证书。然后,您可以从证书颁发机构的官方网站(例如,在我的例子中为 https://www.digicert.com/digicert-root-certificates.htm)搜索此证书的 CRT 文件的相应链接。现在,要包含您的案例中缺少的证书,您可以使用您的 CRT 文件下载链接运行以下命令:

wget https://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt

mv DigiCertSHA2SecureServerCA.crt DigiCertSHA2SecureServerCA.der

openssl x509 -inform DER -outform PEM -in DigiCertSHA2SecureServerCA.der -out DigicertSHA2SecureServerCA.pem.crt

sudo mkdir /usr/share/ca-certificates/extra

sudo cp DigicertSHA2SecureServerCA.pem.crt /usr/share/ca-certificates/extra/

sudo dpkg-reconfigure ca-certificates

在此之后,您可以使用 wget 再次测试您的 URL 以及使用 python urllib 包。有关详细信息,请参阅:https://bugs.launchpad.net/ubuntu/+source/ca-certificates/+bug/1795242


K
Kirby

看一眼

/Applications/Python 3.6/Install Certificates.command

您也可以前往 Finder 中的 Applications 文件夹并点击 Certificates.command


非常感谢!我刚刚转到 Applications 文件夹,找到 Python 文件夹,然后单击 Install Certificates.command 文件。
C
Cherif KAOUA

对于 Centos 6/7、Fedora 上的 Python 3.4+,只需以这种方式安装受信任的 CA:

将 CA.crt 复制到 /etc/pki/ca-trust/source/anchors/update-ca-trust force-enable update-ca-trust extract


可能是个愚蠢的问题,但什么是 CA.crt,我在哪里可以找到它?
N
Noelkd

像你一样,我在我的旧 iMac(OS X 10.6.8)上使用 python 2.7,我也遇到了这个问题,使用 urllib2.urlopen :

urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]

我的程序运行良好,没有 SSL 证书问题,并且突然(在下载程序后),它们因 SSL 错误而崩溃。

问题是使用的python版本:

https://www.python.org/downloads 和 python-2.7.9-macosx10.6.pkg 没有问题,由 Homebrew 工具安装的一个问题:“brew install python”,版本位于 /usr/local/bin .

/Applications/Python 2.7/ReadMe.rtf 中名为 Certificate verification and OpenSSL [CHANGED for Python 2.7.9] 的一章详细解释了这个问题。

因此,请检查、下载并在您的 PATH 中放入正确版本的 python。


这个评论是黄金,不要像我第一次那样忽视它,这为我解决了问题
A
Ads

我半羞愧地低下了头,因为我遇到了同样的问题,除了在我的情况下,我点击的 URL 是有效的,证书是有效的。无效的是我与网络的连接。我未能将代理详细信息添加到浏览器(本例中为 IE)。这阻止了验证过程的正确进行。添加了代理详细信息,然后我的 python 非常高兴。


不要因为忘记某件事而感到羞愧,然后想出来并分享,有人可能会觉得这很有用。虽然使用 IE... 耻辱 :p
B
Brian McCall

带有 centOS 7 的 Amazon EC2 上的 Python 2.7

我必须将环境变量 SSL_CERT_DIR 设置为指向位于 /etc/ssl/certs/ca-bundle.crtca-bundle


您的回答使我走上了正确的道路。在 ubuntu 上,我必须将 SSL_CERT_DIR 设置为 /etc/ssl/certs,并确保 ca-certificates 软件包已安装并且是最新的。
这对我有用,CentOS Linux 版本 7.9.2009。我确实使用了 export SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt。正如查理伯恩斯所指出的,这个问题已经在access.redhat.com/articles/2039753中详细讨论过
М
Максим Стукало

在某些情况下,您不能使用不安全的连接或将 ssl 上下文传递给 urllib 请求。这是我基于 https://stackoverflow.com/a/28052583/6709778 的解决方案

如果您想使用自己的证书文件

import ssl

def new_ssl_context_decorator(*args, **kwargs):
    kwargs['cafile'] = '/etc/ssl/certs/ca-certificates.crt'
    return ssl.create_default_context(*args, **kwargs)

ssl._create_default_https_context = ssl._create_unverified_context

或者您可以使用证书中的共享文件

def new_ssl_context_decorator(*args, **kwargs):
    import certifi
    kwargs['cafile'] = certifi.where()
    return ssl.create_default_context(*args, **kwargs)

Y
Yannis

使用 pip 安装 PyOpenSSL 对我有用(无需转换为 PEM):

pip install PyOpenSSL

v
vperezb

我通过关闭 Fiddler(一个 HTTP 调试代理)解决了这个问题,检查您是否启用了代理,然后重试。


M
MD5

在 python 2.7 中,在文件 C:\Python27\lib\site-packages\certifi\cacert.pem 的末尾添加受信任的根 CA 详细信息有帮助

之后我确实运行(使用管理员权限) pip install --trusted-host pypi.python.org --trusted-host pypi.org --trusted-host files.pythonhosted.org packageName


S
Snehal Parmar

在 Mac 上安装证书解决了我的问题:

pip install certifi

f
fabio.sang

就我而言,我收到此错误是因为 requestsurllib3 版本不兼容,在安装过程中出现以下错误:

ERROR: requests 2.21.0 has requirement urllib3<1.25,>=1.21.1, but you'll have urllib3 1.25 which is incompatible.
pip install 'urllib3<1.25' --force-reinstall

成功了。


P
Peter Tseng

另一个 Anaconda 解决方案。我在 macOS 上的 Python 2.7 环境中获得了 CERTIFICATE_VERIFY_FAILED。事实证明 conda 路径很糟糕:

基础(3.7)环境:

>>> import ssl
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/usr/local/anaconda3/ssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/ssl/certs')

2.7 环境(路径不存在!):

DefaultVerifyPaths(cafile='', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/envs/py27/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/envs/py27/ssl/certs')

修复:

cd /usr/local/anaconda3/envs/py27/
mkdir ssl
cd ssl
ln -s ../../../ssl/cert.pem

a
apresence

我遇到了同样的错误,并且在我放弃并开始自己尝试之前也进行了很长一段时间的疯狂追逐。我最终想通了,所以我想我会分享。就我而言,我在 Linux 上运行 Python 2.7.10(由于我无法控制的原因),无权访问请求模块,无法在操作系统或 Python 级别全局安装证书,无法设置任何环境变量,并且需要访问使用内部颁发的证书的特定内部站点。

注意:禁用 SSL 验证从来都不是一个选项。我正在下载一个立即以 root 身份运行的脚本。如果没有 SSL 验证,任何 Web 服务器都可以伪装成我的目标主机,我只会接受他们给我的任何东西并以 root 身份运行它!

我将 pem 格式的根证书和中间证书(可能有多个)保存到一个文件中,然后使用以下代码:

import ssl,urllib2
data = urllib2.build_opener(urllib2.HTTPSHandler(context=ssl.create_default_context(cafile='/path/to/ca-cert-chain.pem')), urllib2.ProxyHandler({})).open('https://your-site.com/somefile').read()
print(data)

请注意,我在那里添加了 urllib2.ProxyHandler({})。这是因为在我们的环境中默认设置了代理,但它们只能访问外部站点,而不能访问内部站点。如果没有代理绕过,我无法访问内部站点。如果你没有这个问题,你可以简化如下:

data = urllib2.build_opener(urllib2.HTTPSHandler(context=ssl.create_default_context(cafile='/path/to/ca-cert-chain.pem'))).open('https://your-site.com/somefile').read()

像魅力一样工作,并且不会影响安全性。

享受!


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅