Reputation: 176
I tried to send a REST request in python with a certificate based authentication to a given server that is providing the REST api's but after hours of searching and trying I think I need help.
I have a signed certificate from the mentioned server and the key for that cert. The Server itselfs does also provide a certificate for https.
I tried the library httplib.HTTPSConnection:
import httplib import urllib clientCert = "client.crt" clientKey = "client.key" serverCert = 'server.crt' serverApi = "/api/getExample" serverHost = "restapi.example.com" serverPort = 443 requestMethod = "POST" params = urllib.urlencode({'someId': 'myId'}) headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "application/json"} conn = httplib.HTTPSConnection(serverHost, serverPort, key_file=clientKey, cert_file=clientCert) conn.request(requestMethod, serverApi, params, headers) response = conn.getresponse() conn.getresponse() conn.close()
I get ssl.SSLError: SSL: CERTIFICATE_VERIFY_FAILED
Is it possible to get a cert based auth running with that library?
Upvotes: 4
Views: 36179
Reputation: 1
Thank you, Carlo,
I managed to get it working by using a single file for the certificate chain, certificate, and private key. Before this, I was encountering the error: HTTPSConnectionPool(host='host, port=4443): Max retries exceeded with url: /api/endpoint (Caused by SSLError(SSLError(9, '[SSL] PEM lib (_ssl.c:3921)')))
.
Here's the adapted code I used:
import json
import requests
clientCertsAndKey = 'certChainAndCertAndKey.pem'
url = 'https://example.com/api'
payload = { 'someId': 'myID' }
certServer = 'cs.crt'
headers = {'content-type': 'application/json'}
try:
r = requests.post(url, data=json.dumps(payload), verify=certServer,
headers=headers, cert=clientCertsAndKey)
print(r.status_code)
print(r.json())
except requests.exceptions.SSLError as ssl_error:
print(f'SSL error: {ssl_error}')
Just remember, for anyone using a single file for your client certificate + private key, ensure that the certificate chain (certificates of the entities that issued your certificate) is also included in the file. This helped me to overcome the aforementioned SSL error.
Upvotes: -1
Reputation: 176
I was able to get it running with the aid of the "requests" library.
import json
import requests
clientCrt = "cc.crt"
clientKey = "ck.key"
url = "https://example.com/api"
payload = { "someId": "myID" }
certServer = 'cs.crt'
headers = {'content-type': 'application/json'}
r = requests.post(url, data=json.dumps(payload), verify=certServer,
headers=headers, cert=(clientCrt, clientKey))
print(r.status_code)
print(r.json())
Simple as that
Upvotes: 9