Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to get local issuer certificate when using requests in python

here is my code

import requests; url='that website'; headers={   'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',   'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7',   'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' }; r = requests.get(url,headers=headers); print(r); print(r.status_code); 

then it ran into this:

requests.exceptions.SSLError:

HTTPSConnectionPool(host='www.xxxxxx.com', port=44 3):

Max retries exceeded with url: xxxxxxxx (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED]

certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)')))

what should i do?

like image 928
innocentDrifter Avatar asked Aug 20 '18 06:08

innocentDrifter


People also ask

How do I fix unable to get local issuer certificate?

When ssl certificate problem unable to get local issuer certificate error is caused by a self-signed certificate, the fix is to add the certificate to the trusted certificate store. Open the file ca-bundle. crt located in the directory above, then copy and paste the Git SSL certificate to the end of the file.

How do I disable the security certificate check in Python requests?

Method 1: Passing verify=False to request methodAlong with the URL also pass the verify=False parameter to the method in order to disable the security checks.

What is SSL error Python?

SSL certificate_verify_failed errors typically occur as a result of outdated Python default certificates or invalid root certificates. If you're a website owner and you're receiving this error, it could be because you're not using a valid SSL certificate.


2 Answers

It's not recommended to use verify = False in your organization's environments. This is essentially disabling SSL verification.

Sometimes, when you are behind a company proxy, it replaces the certificate chain with the ones of Proxy. Adding the certificates in cacert.pem used by certifi should solve the issue. I had similar issue. Here is what I did, to resolve the issue -

  1. Find the path where cacert.pem is located -

Install certifi, if you don't have. Command: pip install certifi

import certifi certifi.where() C:\\Users\\[UserID]\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\certifi\\cacert.pem 
  1. Open the URL on a browser. Download the chain of certificates from the URL and save as Base64 encoded .cer files.

  2. Now open the cacert.pem in a notepad and just add every downloaded certificate contents (---Begin Certificate--- *** ---End Certificate---) at the end.

like image 177
Indranil Avatar answered Oct 06 '22 09:10

Indranil


If you have already tried to update the CA(root) Certificate using pip:

pip install --upgrade certifi 

or have already downloaded the newest version of cacert.pem from https://curl.haxx.se/docs/caextract.html and replaced the old one in {Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem but it still does not work, then your client is probably missing the Intermediate Certificate in the trust chain.

Most browsers can automatically download the Intermediate Certificate using the URL in "Authority Info Access" section in the Certificate, but Python, Java, and openssl s_client cannot. They rely on the server proactively sending them the intermediate certificate.

Authority Infomation Access

If you speak Chinese you can read this awesome blog: https://www.cnblogs.com/sslwork/p/5986985.html and use this tool to check if the intermediate certificate is sent by / installed on the server or not: https://www.myssl.cn/tools/check-server-cert.html

If you do not, you can check this article: https://www.ssl.com/how-to/install-intermediate-certificates-avoid-ssl-tls-not-trusted/

We can also use openssl in Linux to cross-check this issue:

openssl s_client -connect yourwebsite:443 

openssl: unable to get local issuer certificate The error message is even the same -- "unable to get local issuer certificate". I doubt that "local" here actually means "intermediate".

My current solution for this problem is like @Indranil's suggestion (https://stackoverflow.com/a/57466119/4522434): Export the Intermediate Certificate in browser using base64 X.509 CER format; then use Notepad++ to open it and copy the content into the end of cacert.pem in {Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem

like image 22
Jing He Avatar answered Oct 06 '22 08:10

Jing He