Using SSL Certificates in Python2.7.* - python

I'm on a corporate network I need to use certificates for to get access to certain pages. I've tried looking around online for a module that'll retrieve an HTTPS webpage and also allow me to specify which certificate I want to use. I have this code:
import requests
page = requests.get("https://k9ballistics.com/",'lxml')
thing = page.content
thing = thing.split('\n')
for m in thing:
if '<tr>' in m:
print m
This works on retrieving a normal HTTPS page, but when I try to access our page it throws this error:
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",)
I was hoping to find a way to do it with a module that already comes with Python as opposed to relying on a pip installed package for portability's sake.
I'm on Windows, but I have my certificates from my linux workstation in a folder I'd like to point to, and also have Ubuntu Bash on Windows.

You can pass verify the path to a CA_BUNDLE file or directory with certificates of trusted CAs:
requests.get('https://eg.com', verify='/path/to/certfile.pem')
or persistent:
s = requests.Session()
s.verify = '/path/to/certfile.pem'
Also you can ignore verifying the SSL certificate by verify=False.
Have a look at SSL Cert Verification to see more details.

Related

SSL certificate error - Jupyter notebook

I'm using requests in Jupyter notebooks to make a connection to 'https://dynamodb.eu-west-3.amazonaws.com/ (Amazon AWS) & have been getting the error :-
SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),))
It works with verify=False but I don't want to implement this due to security.
I've been googling solutions for days, trying to set REQUESTS_CA_BUNDLE from cacert.pem to weak.pem, setting SSL_CERT_FILE similarly, using certifi old_where instead of where, downgrading certifi, reinstalling requests with requests[security] - nothing has worked so far. I can connect fine via my browser, so it must be requests or Jupyter notebooks that has the problem or rather is missing the certificate.. I'm able to use requests to other https locations - I'm not sure if they are using SSL encryption or not. I don't know if I need to enable something in the environment or whether I need to get the AWS certificate into my environment variables (and also I don't know how to do either!)
Any help would be much appreciated! Thanks

python bad handshake : certificate verify failed

I'm using the requests package of python and specifying the path to my certificate while making the REST call.
response = requests.get(url, headers=headers, verify=VERIFY_PATH,
cookies=cookiejar)
"VERIFY_PATH" corresponds to the path of the certificate, which is set dynamically.
While things work fine in some environments, they fail in another environment with the following error :
bad handshake: Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)
What is common in all the environments is that I'm using Ubuntu14.04 LTS and requests == 2.13.0
I am not able to understand why its failing in some other enviornments with the same Ubuntu version and requests version. Is there any way I can debug this? Im using the same certificate in all cases, and my certificate is definitely valid because it works in some environments as I mentioned.
Also debug statements show that the correct path to my certificate goes in the requests call, but still the error message.

HTTPS TSL Certificate Chain Validation Using Python Requests

I'm running a windows service using python 2.7.9.
As part of it i'm trying to connect to a server using HTTPS.
I'm using requests model (2.7.0) to do it.
I'm also using wincertstore (0.2) model to read windows certificate store and use it as the CA.
the server certificate is singed using an intermediate certificate in the following order -
Root is "Go Daddy Root Certificate Authority - G2"
Intermediate is "Go Daddy Secure Certificate Authority - G2"
The server certificate "*.demoserver.com"
My problem is that the certificate validation fails with the following error - SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581).
Here is the code i'm using:
import requests
import wincertstore
ca = wincertstore.CertFile()
ca.addcerts('ROOT')
ca.addcerts('CA')
requests.get('https://server.demoserver.com', verify=ca.name)
If I open it on Chrome\Firefox\IE the verification is successful.
I did notice the following behavior:
On a fresh OS, if i open the server using a browser for the first time the intermediate certificate ("Go Daddy Secure Certificate Authority - G2") will be added to Windows certificate store, under that user, under Intermediate Certification Authorities.
If then I will run the code above from a python console the validation will work, since the certificate was added to windows store.
However, since my code is run as a service, and that means using SYSTEM user and local machine store, the certificate won't be there and the validation will fail.
My question is how do I make it work? How can I tell python to check the entire chain, I think it checks the server certificate, sees only one level up (the intermediate certificate), doesn't recognizes it and fails, even though the root certificate is found in the system store also.
I also tried using certifi as the CA which also fails

Python - SSL Client/Server Certificate

I want to create a Client/Server architecture following the python documentation.
This works well with my self-signed certificates in one pem file. (ca_root root_key ca_intermediate intermediate_key)
So my next plan is to create client certificates which can be revoked by the server if the client isn't trustworthy anymore.
So the way to go is that i create a certificate, signed with the intermediate key, and hand it out to the client.
But i still get
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
Do i need to export the whole certificate chain to the client? This seems odd to me.
Thanks!
Most likely you're entire chain isn't in your .pem file. Just copy the text from the certificates in the right order into a single .pem file and attempt that. If that doesn't work you may be getting this error because of your server configuration. More information is need thought to provide a better answer.

Python SSL CERTIFICATE_VERIFY_FAILED

I'm using the following code to interact with a Magento webstore using the XMLRPC api. Magento API Python XMLRPC
Everything was working ok until we made a change on our web server to SSL
Now I'm getting the following error.
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)
I'm not sure why the certificate is failing as we have an EV certificate and all browsers are showing this as ok.
My connection string is:
How can I resolve this / over-ride the code
I'm fairly new to Python so please go easy :o)
magento = MagentoAPI("www.website.co.uk", 443, "myUsername", "myPassword", "/api/xmlrpc", True)
Python, or better the OpenSSL library it is using, can not verify the validity of the certificate of the server. There are many possible reasons: bad configuration, missing intermediate or CA certificate, wrong CN...
A first step could be to go to this site and let it test the SSL/TLS capabilities of the server: https://www.ssllabs.com/ssltest/
It will give you hints on how to solve problems as well.
Python verifies certs via its own bundle, check where it is located by
>>> import certifi
>>> certifi.where()
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-
packages/certifi/cacert.pem'
and add your certificates to the end of that file.

Categories