Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using self-signed certificates with requests in python

Situation : The target site (a pre-prod URL, say https://my-pre-prod-site.com/login, for example) is using a self-signed certificate. From the browser, the site is accessible over https without any issues (the self-signed certificate warning is suppressed by adding the certificate to the trust store in the browser)

Problem Statement : A simple python script that makes a get call to the target site using requests fails with either of the below errors in different situations :

requests.exceptions.SSLError: [Errno 0] _ssl.c:344: error:00000000:lib(0):func(0):reason(0)

or

requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590) The simple script used (on the python prompt) is :

import requests
res = requests.get('https://my-pre-prod-site.com/login')

**Things already tried **

  1. I do NOT want to skip the ssl verification. Hence, verify = false is not an option for me.
  2. I have already used the below with the same error

res = requests.get('https://my-pre-prod-site.com/login', verify = os.path.join(os.getcwd(),'test.pem') where test.pem is a pem file created by concatenating the output of the below commands in that order :

openssl rsa -in ~/Desktop/CertPath/private.key -check

and

openssl x509 -pubkey -noout -in ~/Desktop/CertPath/certificate.pem

The script is run from ~/Desktop/CertPath so getcwd() gives the right path to the certificate.

  1. I tried another test.pem file as well where the order of concatenation was reversed. It still throws the same error.
  2. Have tried passing the .pem file holding the public key and the .key file holding the private key, separately (individually) as well, with the same error as the outcome.

Environment details if it helps

OS - ElCapitan Mac
Requests - 2.9.0
Python - 2.7.10
OpenSSL being used by Python - 'OpenSSL 0.9.8zg 14 July 2015'

Note - The openssl version does not seem to be an issue. Because even with an updated version of openssl, the errors are the same - tested on Ubuntu with Python 2.6 that uses the Openssl 1.x

like image 889
qre0ct Avatar asked Jan 13 '16 13:01

qre0ct


People also ask

How do I request Python to trust a self signed SSL certificate?

Trust a self signed certificate in Python requests In the event you see this error, you will need to explicitly trust the certificates being returned by the external system if indeed they are to be trusted. To do this, use the verify parameter in your requests code to trust the certificate.

Why we should not use self-signed certificate?

Not trusted by browsers and users Self-signed certificates contain private and public keys within the same entity, and they cannot be revoked, thus making it difficult to detect security compromises.

What are the limitations of using self-signed certificates?

One of the key limitations of self-signed certificates is often mistaken for a benefit: self-signed certificates cannot be revoked, and they never expire. This makes a compromised certificate difficult to identify, which several security challenges.

Does Python requests use https?

Requests verifies SSL certificates for HTTPS requests, just like a web browser.


1 Answers

This question is old but In case someone wonders off here.

You are putting the private key and public key in you test.pem. This is wrong. What verify param requires is certs which it can trust.

res = requests.get('https://my-pre-prod-site.com/login', verify = os.path.join(os.getcwd(),'test.pem')

The test.pem is supposed to contain the list of all the Trusted Certificates. But what you're providing in your test.pem is your public and private key. You're ~/Desktop/CertPath/certificate.pem file itself should go into it.

Try this:

res = requests.get('https://my-pre-prod-site.com/login', verify = '~/Desktop/CertPath/certificate.pem')
like image 107
user3493833 Avatar answered Sep 20 '22 01:09

user3493833