I have been provided with a pem certificate to authenticate with a third party. Authenticating using certificates is a new concept for me.
Inside are two certificates and a private key.
The issuer has advised they do not support SSL verification but use TLS(1.1/1.2).
I have run a script as below:
import requests as req
import json
url = 'https://url.com/call'
certificate_file = "C:/certs/cert.pem"
headers = {"Content-Type": "application/json"}
req_body ={
"network":{
"network_id": 12345
},
"branch":{
"branch_id": 12345,
},
"export_period":{
"start_date_time": "16-11-2021 00:00:00",
"end_date_time": "17-11-2021 00:00:00"
}
}
jsonObject = json.dumps(req_body)
response = req.post(url,headers=headers,params=jsonObject,verify=certificate_file)
I'm getting the following error:
SSLError: HTTPSConnectionPool(host='url.com, port=443): Max retries exceeded with url: /call?%7B%22network%22:%20%7B%22network_id%22:%2012345%7D,%20%22branch%22:%20%7B%22branch_id%22:%2012345%7D,%20%22export_period%22:%20%7B%22start_date_time%22:%20%2216-11-2021%2000:00:00%22,%20%22end_date_time%22:%20%2217-11-2021%2000:00:00%22%7D%7D (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)')))
Would appreciate guidance, my gut says I should be doing something specific for TLS hence the SSL error.
PEM or Privacy Enhanced Mail is a Base64 encoded DER certificate. PEM certificates are frequently used for web servers as they can easily be translated into readable data using a simple text editor. Generally when a PEM encoded file is opened in a text editor, it contains very distinct headers and footers.
Types include: Kwashiorkor (protein malnutrition predominant) Marasmus (deficiency in calorie intake) Marasmic kwashiorkor (marked protein deficiency and marked calorie insufficiency signs present, sometimes referred to as the most severe form of malnutrition)
However the default location for certificates is /etc/ssl/certs . You might find additional certificates there. This will list all the . pem files present on your system and their full path.
The .pem file is now ready to use. Log into your DigiCert Management Console and download your Intermediate (DigiCertCA.crt) and Primary Certificates (your_domain_name.crt). Open a text editor (such as wordpad) and paste the entire body of each certificate into one text file in the following order:
The PEM format is also used to store private keys and certificate signing requests (CSRs): -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----.
privkey.pem is an RSA private key generated alongside the certificate. These may also use the .crt extension; if you’ve self-signed a certificate with OpenSSL, you’ll get a CRT file rather than PEM, though the contents will still be the same, and the usage will be the same.
PEM files are containers meant to verify and decrypt data that a server sends. A CRT (which stands for certificate) file represents a certificate signing request. CRT files are a way to verify ownership without private key access.
The issuer is using an up to date version of HTTPS - SSL is the commonly used term but TLS is the more correct one. Sounds like their setup is correct - meaning you need to call it with a trusted client certificate, as part of an HTTPS request.
I would recommend doing it with the curl tool first so that you can verify that the API works as expected.
curl -s -X GET "https://api.example.com/test" \
--cert ./certs/example.client.pem \
--key ./certs/example.client.key \
--cacert ./certs/ca.pem \
-H "Content-Type: application/json"
Split the certs into separate files as above. Sounds like one of them is a root certificate authority that you need to tell the client tech stack to trust - for curl this is done using the cacert
parameter as above.
Once this is working you can follow the same approach in the Python requests library. I believe this uses cert
and verify
parameters like this. So it looks like your code is not far off.
result = requests.get(
'https://api.example.com',
cert=('example.pem', 'example.key'),
verify='ca.pem')
MORE ABOUT MUTUAL TLS
Out of interest, if you ever want to demystify Mutual TLS and understand more, have a look at these advanced Curity resources:
These include an OpenSSL Script you can run, to see what the separated certificate files should look like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With