抛出SSLError的Python请求

Ted*_*ows 309 python ssl urllib3 python-requests

我正在编写一个涉及CAS,jspring安全检查,重定向等的简单脚本.我想使用Kenneth Reitz的python请求,因为它是一项很棒的工作!但是,CAS需要通过SSL进行验证,因此我必须先通过该步骤.我不知道Python的要求是什么?这个SSL证书应该驻留在哪里?

Traceback (most recent call last):
  File "./test.py", line 24, in <module>
  response = requests.get(url1, headers=headers)
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
  File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 209, in request 
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 624, in send
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 300, in _build_response
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 611, in send
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Run Code Online (Sandbox Code Playgroud)

Raf*_*ida 402

您遇到的问题是由不受信任的SSL证书引起的.

像之前评论中提到的@dirk一样,最快的修复是设置verify=False:

requests.get('https://example.com', verify=False)
Run Code Online (Sandbox Code Playgroud)

请注意,这将导致证书无法验证.这将使您的应用程序面临安全风险,例如中间人攻击.

当然,应用判断.正如评论中所提到的,这对于快速/一次性应用程序/脚本来说可能是可以接受的,但实际上不应该转到生产软件.

如果仅在特定上下文中跳过证书检查是不可接受的,请考虑以下选项,最佳选择是将verify参数设置为字符串,该字符串是.pem证书文件的路径(您应该通过某种安全方式获取该文件的路径)手段).

因此,从版本2.0开始,该verify参数接受以下值及其各自的语义:

  • True:使证书针对库自己的可信证书颁发机构进行验证(注意:您可以通过Certifi库查看哪些根证书请求使用,证书库是从请求中提取的RC信任数据库:Certifi - 人类信任数据库).
  • False:完全绕过证书验证.
  • 用于验证证书的请求的CA_BUNDLE文件的路径.

来源:请求 - SSL证书验证

另请查看cert同一链接上的参数.

  • @ khalid13:一把斧头"起作用"作为头痛药(没有头 - 没有头痛).这并不意味着以这种方式使用它是一个好主意.`verify = False`禁用主机的SSL证书检查. (39认同)
  • @JFSebastian老实说,这取决于你在做什么.对于我的快速/一次性应用程序,这已经足够了. (23认同)
  • @diyism做出这样的改变听起来*非常*不安全...... (5认同)
  • 这没有标记为正确,但我可以验证它是否有效(与下面的答案相反). (2认同)

Bou*_*oud 105

来自请求SSL验证的文档:

请求可以验证HTTPS请求的SSL证书,就像Web浏览器一样.要检查主机的SSL证书,可以使用verify参数:

>>> requests.get('https://kennethreitz.com', verify=True)
Run Code Online (Sandbox Code Playgroud)

如果您不想验证您的SSL证书,请制作 verify=False

  • 如果您有自签名证书,则下载它并将verify设置为其文件名.设置verify = False没有任何借口.验证= '/路径/到/ cert.pem' (16认同)
  • 如果您不想验证证书,请设置verify = False,如果您有自签名证书,请将其设置为iow (14认同)
  • 抱歉Boud,我需要对这个答案进行投票,因为请求不像"Web浏览器"那样处理HTTPS请求.如果未在服务器上声明完整的SSL信任链(包括中间证书)并需要额外的证书下载,您将收到上述SSL验证错误.Web浏览器将执行额外下载,而不会标记任何证书错误.这是Web浏览器和请求不同的一种方式.还有其他人.请求会进行一些验证,但它不如浏览器好. (14认同)
  • 好吧,我添加了verify = True,但仍然收到完全相同的错误.没变.必须要有其他东西,但不知道它可能是什么. (3认同)

jfs*_*jfs 50

要使用的CA文件的名称可以通过verify:

cafile = 'cacert.pem' # http://curl.haxx.se/ca/cacert.pem
r = requests.get(url, verify=cafile)
Run Code Online (Sandbox Code Playgroud)

如果您使用,verify=Truerequests使用其自己的CA集,该CA集可能没有签署服务器证书的CA.

  • @ 9emE0iL18gxCqLT:为什么你认为所有系统都使用你提供的路径?`requests`可以打包为您的发行版.运行[`python -mrequests.certs`](https://github.com/kennethreitz/requests/blob/master/requests/certs.py)以找出它指向的位置. (11认同)
  • 你不应该使用curl的`cacert.pem`.它包含许多已撤销的证书.查看Certifi(请求使用):https://certifi.io (5认同)
  • @KennethReitz:1-请求使用失败的OP(否则没有问题)2- [`cacert.pem`是从Mozilla(通过cURL)提取的CA证书](https://curl.haxx.se /docs/caextract.html) - 这只是一个例子(如果流行的网络浏览器使用的CA列表不能用作示例,那么我不知道可能是什么) - 这一点如果默认列表失败,请回答您*可以*传递您自己的CA文件. (3认同)
  • 如果Python请求的cacert包已过期,我该如何更新它? (2认同)

ala*_*jds 38

$ pip install -U requests[security]

  • 在Python 2.7.6 @ Ubuntu 14.04.4 LTS上测试
  • 在Python 2.7.5 @ MacOSX 10.9.5(Mavericks)上测试

当这个问题被打开时(2012-05),请求版本是0.13.1.在版本2.4.1(2014-09)中,使用certifi包(如果可用)引入了"安全性"附加功能.

现在(2016-09)主版本是2.11.1,没有 合适的版本verify=False.requests.get(url, verify=False)如果安装requests[security]附加功能,则无需使用.

  • 由`pip install -U requests [security] --no-cache`修复两次和`pip install certifi == 2015.04.28` (7认同)
  • 在安装请求安全包之前执行`pip install --upgrade pip`以避免其他错误 (3认同)

小智 31

我在使用aws boto3时遇到了同样的问题和ssl证书验证失败问题,通过查看boto3代码,我发现REQUESTS_CA_BUNDLE没有设置,所以我通过手动设置修复了这两个问题:

from boto3.session import Session
import os

# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
    '/etc/ssl/certs/',
    'ca-certificates.crt')
# centos
#   'ca-bundle.crt')
Run Code Online (Sandbox Code Playgroud)

对于aws-cli,我猜设置REQUESTS_CA_BUNDLE ~/.bashrc将解决这个问题(未经测试,因为我的aws-cli无需工作).

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE
Run Code Online (Sandbox Code Playgroud)

  • 这解决了我的问题!我在Mac上使用Charles Proxy调试一个对HTTPS API进行JSON调用的库。我按照指定的方式安装了Charless证书,并将其添加到钥匙串中,但是Python始终失败:SSLError:(“错误的握手:Error([('SSL例程','ssl3_get_server_certificate','证书验证失败')],)”)“ ,)为了解决这个问题,我最终听从了您关于添加REQUESTS_CA_BUNDLE并从钥匙串中将Charles证书导出为.pem文件的建议。现在,它起作用了! (2认同)

tin*_*tin 18

如果你有一个依赖的库requests而你无法修改验证路径(比如pyvmomi),那么你必须找到cacert.pem捆绑的请求并将你的CA附加到那里.以下是查找cacert.pem位置的通用方法:

视窗

C:\>python -c "import requests; print requests.certs.where()"
c:\Python27\lib\site-packages\requests-2.8.1-py2.7.egg\requests\cacert.pem
Run Code Online (Sandbox Code Playgroud)

Linux的

#  (py2.7.5,requests 2.7.0, verify not enforced)
root@host:~/# python -c "import requests; print requests.certs.where()"
/usr/lib/python2.7/dist-packages/certifi/cacert.pem

#  (py2.7.10, verify enforced)
root@host:~/# python -c "import requests; print requests.certs.where()"
/usr/local/lib/python2.7/dist-packages/requests/cacert.pem
Run Code Online (Sandbox Code Playgroud)

顺便说一句.@ requests-devs,将你自己的cacerts与请求捆绑在一起真的非常烦人......尤其是你似乎没有先使用系统ca存储这一事实,这在任何地方都没有记录.

更新

在您使用库并且无法控制ca-bundle位置的情况下,您还可以将ca-bundle位置明确设置为主机范围的ca-bundle:

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt python -c "import requests; requests.get('https://somesite.com';)"
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用自签名证书怎么办?在这种情况下,CA 会是什么? (2认同)

use*_*581 14

我使用gspread面临同样的问题,这些命令对我有用:

sudo pip uninstall -y certifi
sudo pip install certifi==2015.04.28
Run Code Online (Sandbox Code Playgroud)

  • 这有一个缺点,即从旧版本的certifi重新安装可能已撤销/不受信任的证书,不建议这样做. (4认同)

Ani*_*ole 12

如果要删除警告,请使用以下代码.

import urllib3

urllib3.disable_warnings()
Run Code Online (Sandbox Code Playgroud)

verify=Falserequest.getpost方法


chk*_*chk 11

我找到了解决类似问题的具体方法.这个想法指向存储在系统中的cacert文件,并由另一个基于ssl的应用程序使用.

在Debian中(我不确定在其他发行版中是否相同)证书文件(.pem)存储在/etc/ssl/certs/So中,这是适合我的代码:

import requests
verify='/etc/ssl/certs/cacert.org.pem'
response = requests.get('https://lists.cacert.org', verify=verify)
Run Code Online (Sandbox Code Playgroud)

为了猜测pem选择哪个文件,我浏览到了url并检查哪个证书颁发机构(CA)已生成证书.

编辑:如果你不能编辑代码(因为你正在运行第三个应用程序),你可以尝试pem直接添加证书/usr/local/lib/python2.7/dist-packages/requests/cacert.pem(例如将其复制到文件的末尾).

  • [相关文章](http://stackoverflow.com/a/9031701/1538221)用于调试python使用的CA_BUNDLE. (2认同)

小智 10

正如其他人所指出的,这个问题“是由不受信任的 SSL 证书引起的”。我的回答是基于评分最高的答案这个答案

您可以使用curl以下方法测试证书:

curl -vvI https://example.com
Run Code Online (Sandbox Code Playgroud)

如果返回错误,您有 3 个选择:

  1. 为了快速修复,您可以不验证证书:
curl -vvI https://example.com
Run Code Online (Sandbox Code Playgroud)
  1. 将路径传递到带有受信任 CA 证书的 CA_BUNDLE 文件或目录:
requests.get('https://example.com', verify=False)
Run Code Online (Sandbox Code Playgroud)
  1. 如果您有权访问,请修复 Web 服务器证书。

我的问题是因为我只使用了我网站的证书,而不是中间(又名链)证书。

如果您使用 Let's Encrypt,则应使用该fullchain.pem文件,而不是cert.pem.


小智 8

如果你不打扰证书只是使用verify=False.

import requests

url = "Write your url here"

returnResponse = requests.get(url, verify=False)
Run Code Online (Sandbox Code Playgroud)


mic*_*ael 7

经过几个小时的调试后,我只能使用以下包来实现这一点:

requests[security]==2.7.0  # not 2.18.1
cryptography==1.9  # not 2.0
Run Code Online (Sandbox Code Playgroud)

运用 OpenSSL 1.0.2g 1 Mar 2016

没有这些包verify=False没有工作.

我希望这可以帮助别人.


小智 5

我遇到了同样的问题.事实证明我没有在我的服务器上安装中间证书(只需将其附加到证书的底部,如下所示).

https://www.digicert.com/ssl-support/pem-ssl-creation.htm

确保安装了ca-certificates软件包:

sudo apt-get install ca-certificates
Run Code Online (Sandbox Code Playgroud)

更新时间也可以解决此问题:

sudo apt-get install ntpdate
sudo ntpdate -u ntp.ubuntu.com
Run Code Online (Sandbox Code Playgroud)

如果您使用的是自签名证书,则可能需要手动将其添加到系统中.


xme*_*eko 5

如果请求调用隐藏在代码深处并且您不想安装服务器证书,那么仅出于调试目的,可以对请求进行猴子补丁:

import requests.api
import warnings


def requestspatch(method, url, **kwargs):
    kwargs['verify'] = False
    return _origcall(method, url, **kwargs)

_origcall = requests.api.request
requests.api.request = requestspatch
warnings.warn('Patched requests: SSL verification disabled!')
Run Code Online (Sandbox Code Playgroud)

切勿在生产中使用!


d-c*_*der 5

我想参加聚会为时已晚,但我想为像我这样的流浪者粘贴修复程序!所以以下在 Python 3.7.x 上对我有用

在终端中输入以下内容

pip install --upgrade certifi      # hold your breath..
Run Code Online (Sandbox Code Playgroud)

再次尝试运行您的脚本/请求,看看它是否有效(我确定它不会被修复!)。如果它不起作用,请尝试直接在终端中运行以下命令

open /Applications/Python\ 3.6/Install\ Certificates.command  # please replace 3.6 here with your suitable python version
Run Code Online (Sandbox Code Playgroud)