2

While writing POST REQUEST in Python, I've faced some issue:

self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1108)

I don't want to set: verify = False in the REQUESTS.

How I can handle this problem?

syeenn
  • 191
  • 2
  • 3
  • 11

3 Answers3

2

The error happens because the certificate being used by the server was not issued by a certificate authority (CA) included in the default list of trusted CAs used by the requests module. It is a self-signed certificate, so you either need to tell requests explicitly to trust that individual cert, or (preferably, if the server is under your control), get a certificate signed by one of the trusted CAs and make the server use that instead.

To trust only the exact certificate being used by the server, download it and instead of setting verify=False, set verify="/path/to/cert.pem", where cert.pem is the server certificate.

Phydeaux
  • 2,795
  • 3
  • 17
  • 35
  • the error even says "self signed certificate", so most likely your assumption is correct. – umläute Nov 19 '20 at 12:12
  • ah yes, didn't see that – Phydeaux Nov 19 '20 at 12:14
  • @Phydeaux: Can you give the path where ca-bundle.pem is stored? – syeenn Nov 19 '20 at 12:17
  • @SylwiaKrakowska see edits - the certificate is self-signed, so there is no separate CA bundle - you need to save the server certificate somewhere (you choose where) and tell `requests` where to find it. – Phydeaux Nov 19 '20 at 12:21
  • @Phydeaux: I tried with verify = "C:/Users/XXX/AppData/Local/Programs/Python/Python38/Lib/test/cert.pem") but i run into next issue: ```raise IOError("Could not find a suitable TLS CA certificate bundle, " OSError: Could not find a suitable TLS CA certificate bundle, invalid path```. Can you help me on that? – syeenn Nov 19 '20 at 12:34
1

Here are some more detailed instructions on creating the correct .pem file:

The following URL has instructions for downloading SSL certificates from a website using various browsers. You need to create a certificate-chain .pem file and for that you need to use Firefox. We will pretend that google.com was the website with which you were having difficulty. When you get to the Certificate page, you will see something like the following:

enter image description here

In this example you can chose either GTS CA 101 or GlobalSIGN and then click on the PEM (chain) download link. This will create a file google-com-chain.pem in the directory of your choice.

Then wherever the source specified verify=False, replace it with `verify='/path-to/google-com-chain.pem'

Booboo
  • 38,656
  • 3
  • 37
  • 60
1

import request
response = requests.get("url/api that you want to hit", verify="path to ssl certificate")

For me the problem was that none of the above answers completely helped me but gave me the right direction to look at.

For sure, SSL certificate is needed but when you are behind the company's firewall then publicly available certificates might not help. You might need to reach out to the IT department of your company to obtain the certificate as each company uses special certificate from the security provider they have contracted the services from. And place it in a folder and pass the path to that folder as an argument to verify parameter.

For me even after trying all the above solutions and using the wrong certificate I was not able to make it work. So just remember for those who are behind company's firewall to obtain the right certificate. It can make a difference between success and failure of your request call.

In my case I placed the certificate in the following path and it worked like magic.

C:\Program Files\Common Files\ssl

You could also refer https://2.python-requests.org/en/master/user/advanced/#id3 which talks about ssl verification

Harpreet
  • 165
  • 1
  • 8