Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PEM Certificate & TLS Verification against REST api

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.

like image 781
TJB Avatar asked Nov 17 '21 17:11

TJB


People also ask

What is a PEM cert?

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.

What is PEM example?

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)

Where do I find certificate PEM?

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.

How do I use the PEM file for my certificate?

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:

What is the PEM format used for?

The PEM format is also used to store private keys and certificate signing requests (CSRs): -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----.

What is a private key PEM file?

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.

What is the difference between a CRT file and a pem file?

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.


Video Answer


1 Answers

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:

  • Mutual TLS Secured API
  • Code Sample

These include an OpenSSL Script you can run, to see what the separated certificate files should look like.

like image 63
Gary Archer Avatar answered Oct 11 '22 06:10

Gary Archer