0

I'm trying to figure out how to specify an SSLContext with Request.

I have two functions which in theory should do the same, however the one with Requests doesn't work.

def func_OK(token):
    ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH,cafile='myCA.crt.pem')
    ctx.load_cert_chain(certfile='myprivate.pem')
    url = 'https://my_url.com'
    hdr = {"Content-Type": "application/json","Authorization":"Bearer "+token}
    data = '{"filterList":[{}]}'
    bdata = data.encode('utf-8')
    req = urllib.request.Request(url, headers=hdr)
    resp = urllib.request.urlopen(req, data=bdata, context=ctx)
    content = resp.read()
    data = json.loads(content.decode('utf-8'))
def func_NOK(token):
    import requests
    url = 'https://my_url.com'
    hdr = {"Content-Type": "application/json","Authorization":"Bearer "+token}
    data = '{"filterList":[{}]}'
    bdata = data.encode('utf-8')
    resp = requests.post(url,headers=hdr, data={"filterList":[{}]})

The only the difference between the two functions are the sslContext. In the func_NOK, I try :

  1. resp = requests.post(url,headers=hdr, data={"filterList":[{}]}, verify=False) - it doesn't work
  2. resp = requests.post(url,headers=hdr, data={"filterList":[{}]}, cert=('myCA.crt.pem','myprivate.pem')) - it doesn't work
  3. resp = requests.post(url,headers=hdr, data={"filterList":[{}]}, verify="concat_file.crt") with "concat_file.crt" file a concatenation of 'myCA.crt.pem' and 'myprivate.pem'

In any cases I have an SSL error. For example, on my last example the error msg is :

requests.exceptions.ConnectionError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1131)

I'm just trying to use an SSLContext with Requests.

ti7
  • 16,375
  • 6
  • 40
  • 68
user5023028
  • 35
  • 1
  • 6

3 Answers3

0
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH,cafile='myCA.crt.pem')
ctx.load_cert_chain(certfile='myprivate.pem')

load_cert_chain loads the cert and private key for use as client certificate - which would be the cert argument with requests. cafile describes the CA it should use to verify the server certificate - which would be the verify argument for requests. Combined this would result in:

requests.post(..., cert='myprivate.pem', verify='myCA.crt.pem')
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Unfortunately it doesn't work. Error msg : (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1131)'))) – user5023028 Feb 07 '22 at 20:20
0

I find where my cacert.pem : /home/<soome_path>/pyEnv/myEnv/lib/python3.8/site-packages/certifi/cacert.pem

I concatenated the files : myCA.crt.pem >> cacert.pem myprivate.pem>> cacert.pem

then I specified the path using verify : requests.post(...,verify='/home/<soome_path>/pyEnv/myEnv/lib/python3.8/site-packages/certifi/cacert.pem')

And I don't have the ssl error anymore. However I retrieve an html msg instead of a json. Maybe an issue on the parameters that I send to the endpoint.

user5023028
  • 35
  • 1
  • 6
  • 1
    myprivate.pem was not given as CA in your original func_OK, so it should not be necessary here either. As for needing cacert.pem - it would be really interesting to know more about the server certificate and how it relates to myCA.crt.pem and the publicly trusted CA in cacert.pem. – Steffen Ullrich Feb 07 '22 at 20:38
0

I solved it using : requests.post(url,headers=hdr,json={"filterList":[{}]}, cert='myprivate.pem')

user5023028
  • 35
  • 1
  • 6
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 09 '22 at 03:47