Python query throwing SSLError

I am working on a simple script that includes CAS, jspring security check, redirection, etc. I would like to use Python queries Kenneth Reitz, because it is a great job! However, CAS requires confirmation via SSL, so I need to go through this step first. I don't know what Python queries want? Where should this SSL certificate be located?

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 
+301
python ssl python-requests urllib3
May 19 '12 at 18:45
source share
18 answers

The problem you encountered is caused by an untrusted SSL certificate.

Like @dirk mentioned in the previous comment, the fastest solution is to verify=False .

Please note that this will result in the certificate not being verified. This exposes your application to security risks such as man-in-the-center attacks.

Of course, apply judgment. As mentioned in the comments, this may be acceptable for applications / quick / drop scenarios, but you should not actually access the software.

If just skipping certificate verification is unacceptable in your specific context, consider the following options, your best option is to set the verify parameter to a string that is the path of the certificate .pem file (which you should obtain using some secure means).

So, starting with version 2.0, the verify parameter takes the following values ​​with its corresponding semantics:

  • True : calls a certificate to authenticate its own library of trusted certificates for the library (Note: you can see which root certificate requests are used through the Certifi library, RC trust database extracted from requests: Certifi - Trust Database for people ).
  • False : completely bypass certificate verification.
  • The path to the CA_BUNDLE file for requests used to verify certificates.

Source: Requests - SSL Certificate Validation

Also consider the cert parameter at the same link.

+393
Oct 12 '12 at 18:19
source share

From the requests, the SSL verification documentation :

Requests can verify SSL certificates for HTTPS requests, just like a web browser. To verify the SSL certificate of hosts, you can use the validation argument:

 >>> requests.get('https://kennethreitz.com', verify=True) 

If you do not want to verify your SSL certificate, do verify=False

+105
May 19 '12 at 19:20
source share

The CA file name you can use can be passed through verify :

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

If you use verify=True , then requests uses its own set of CAs, which may not have the CAs that signed your server certificate.

+49
Oct 12 '12 at 18:38
source share

$ pip install -U requests[security]

  • Tested in Python 2.7.6 @Ubuntu 14.04.4 LTS
  • Tested in Python 2.7.5 @MacOSX 10.9.5 (Mavericks)

When this question was opened (2012-05), the query version was 0.13.1. In version 2.4.1 (2014-09) , additional security features were added using the certifi package, if available.

Right now (2016-09) the main version is 2.11.1, which works well without verify=False , used as requests.get(url, verify=False) if installed with additional requests[security] .

+37
Sep 19 '16 at 18:57
source share

I ran into the same problem and the ssl certificate confirmed the error when using aws boto3, looking at the boto3 code, I found that REQUESTS_CA_BUNDLE not installed, so I fixed both issues by installing it manually:

 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') 

For aws-cli, I believe that setting REQUESTS_CA_BUNDLE to ~/.bashrc will fix this problem (not tested because my aws-cli works without it).

 REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt export REQUESTS_CA_BUNDLE 
+29
Nov 15 '15 at 7:47
source share

If you have a library that relies on requests , and you cannot change the verification path (for example, using pyvmomi ), you will have to find cacert.pem complete with requests and add your own CA. Here's a general approach to finding cacert.pem location:

window

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

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 

by the way. @ request-devs, linking your own cacerts to the request is really very annoying ... especially the fact that you don't seem to be using the ca store system and this is not documented anywhere.

Update

in situations where you use the library and do not have control over the location of ca-bundle, you can also explicitly specify the location of ca-bundle as your clock package:

 REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt python -c "import requests; requests.get('https://somesite.com';)" 
+18
Mar 04 '16 at 8:38
source share

I am facing the same problem using gspread and these commands work for me:

 sudo pip uninstall -y certifi sudo pip install certifi==2015.04.28 
+14
Feb 16 '16 at 4:53 on
source share

If you want to remove warnings, use the code below.

 import urllib3 urllib3.disable_warnings() 

and verify=False using the request.get or post method

+12
Nov 03 '15 at 7:42
source share

I found a specific approach to solve a similar problem. The idea points to a cacert file stored on the system and used by other ssl-based applications.

In Debian (I'm not sure if it is the same in other distributions) certificate files (.pem) are stored in /etc/ssl/certs/ So this is the code that works for me:

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

To guess which pem to choose, I look at the URL and check which certificate (CA) generated the certificate.

EDIT: if you cannot edit the code (because you are using the third application), you can try adding the pem certificate directly to /usr/local/lib/python2.7/dist-packages/requests/cacert.pem (e.g. copy it to the end of the file).

+11
Apr 18 '13 at 14:29
source share

If you are not worried about the certificate, just use verify=False .

 import requests url = "Write your url here" returnResponse = requests.get(url, verify=False) 
+8
May 21 '15 at 12:01
source share

After hours of debugging, I could only get this to work with the following packages:

 requests[security]==2.7.0 # not 2.18.1 cryptography==1.9 # not 2.0 

using OpenSSL 1.0.2g 1 Mar 2016

Without these packages verify=False did not work.

I hope this helps someone.

+7
Jul 20 '17 at 20:10
source share

I ran into the same problem. It turns out that I did not install the intermediate certificate on my server (just add it to the end of your certificate, as shown below).

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

Make sure you have the ca certificate package installed:

 sudo apt-get install ca-certificates 

Updating time may also solve the following:

 sudo apt-get install ntpdate sudo ntpdate -u ntp.ubuntu.com 

If you use a self-signed certificate, you may have to add it to your system manually.

+5
Jun 13 '14 at 19:19
source share

If the call requests are hidden somewhere deep in the code, and you do not want to install a server certificate, then for debugging purposes only, you can request monkeypatch:

 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('Pathched requests: SSL verification disabled!') 

Never use in production!

+4
Aug 29 '17 at 6:06 on
source share

I struggled with this problem in HOURS.

I tried to update requests. Then I updated certifi. I indicated to check certifi.where () (the code does this by default anyway). Nothing succeeded.

Finally, I upgraded my python version to python 2.7.11. I was on Python 2.7.5, which had some incompatibilities with the way certificates are verified. As soon as I updated Python (and several other dependencies), it started working.

+3
May 6 '16 at
source share

The query module is currently experiencing a problem causing this error, introduced in v2.6.2 - v2.12.4 (ATOW): https://github.com/kennethreitz/requests/issues/2573

The workaround for this problem is to add the following line: requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'

+2
Jan 15 '17 at 20:10
source share

As @Rafael Almeida has already mentioned, the problem you encountered is caused by an untrusted SSL certificate. In my case, the SSL certificate was not trusted by my server. To get around this without compromising security, I downloaded the certificate and installed it on the server (just double-clicking the .crt file and then installing the certificate ...).

+1
Jun 14 '17 at 11:07 on
source share

It is not possible to add options if requests are called from another package. In this case, adding certificates to the cacert package is a direct path, for example. I had to add "StartCom Class 1 Primary Intermediate Server CA", for which I uploaded the root certificate to StartComClass1.pem. since my virtualenv is called caldav, I added the certificate with:

 cat StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/pip/_vendor/requests/cacert.pem cat temp/StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/requests/cacert.pem 

one of them may be enough, I did not check

0
Aug 03 '15 at 17:29
source share

I had a similar or the same certificate validation issue. I read that versions of OpenSSL are less than 1.0.2, whose requests sometimes depend on validating strong certificates (see here ). CentOS 7 seems to be using 1.0.1e, which seems to have a problem.

I was not sure how to get around this issue on CentOS, so I decided to allow weaker licenses for 1024 bit CA.

 import certifi # This should be already installed as a dependency of 'requests' requests.get("https://example.com", verify=certifi.old_where()) 
0
Jul 11 '17 at 13:26
source share



All Articles