urllib 和“SSL:CERTIFICATE_VERIFY_FAILED"错误 [英] urllib and "SSL: CERTIFICATE_VERIFY_FAILED" Error

查看:94
本文介绍了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)>

这是导致此错误的代码:

This is the code that is causing this error:

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.如何让它绕过验证?

The API I'm using requires me to use HTTPS. How can I make it bypass the verification?

推荐答案

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

If you just want to bypass verification, you can create a new SSLContext. By default newly created contexts use CERT_NONE.

请注意17.3.7.2.1

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

When calling the SSLContext constructor directly, CERT_NONE is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you’re talking to. Therefore, when in client mode, it is highly recommended to use CERT_REQUIRED.

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

But if you just want it to work now for some other reason you can do the following, you'll have to import ssl as well:

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] 因为您现在没有验证证书!

This should get round your problem but you're not really solving any of the issues, but you won't see the [SSL: CERTIFICATE_VERIFY_FAILED] because you now aren't verifying the cert!

要补充上述内容,如果您想更多地了解为什么会看到这些问题,您需要查看 PEP 476.

To add to the above, if you want to know more about why you are seeing these issues you will want to have a look at PEP 476.

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

This PEP proposes to enable verification of X509 certificate signatures, as well as hostname verification for Python's HTTP clients by default, subject to opt-out on a per-call basis. This change would be applied to Python 2.7, Python 3.4, and Python 3.5.

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

There is an advised opt out which isn't dissimilar to my advice above:

import ssl

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

它还通过monkeypatching提供了一个非常不鼓励的选项在python中不经常看到:

It also features a highly discouraged option via monkeypatching which you don't often see in python:

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

用创建未经验证的上下文的函数覆盖上下文创建的默认函数.

Which overrides the default function for context creation with the function to create an unverified context.

请注意 PEP 中的说明:

Please note with this as stated in the PEP:

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

This guidance is aimed primarily at system administrators that wish to adopt newer versions of Python that implement this PEP in legacy environments that do not yet support certificate verification on HTTPS connections. For example, an administrator may opt out by adding the monkeypatch above to sitecustomize.py in their Standard Operating Environment for Python. Applications and libraries SHOULD NOT be making this change process wide (except perhaps in response to a system administrator controlled configuration setting).

如果您想阅读有关为什么不验证证书在软件中不好的论文 你可以在这里找到

If you want to read a paper on why not validating certs is bad in software you can find it here!

这篇关于urllib 和“SSL:CERTIFICATE_VERIFY_FAILED"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆