15

I want to use Python Requests to get the contents of internal company web page (say, https://internal.com). I can see this page in the browser, and I can "view the certificate."

So now I want to get the web page with Requests, so I do:

import requests
requests.get('https://internal.com')

But then I get an SSLError:

SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

So I guess I need to specify a cert file:

requests.get('https://example.com', cert=('/path/server.crt', '/path/key'))

But how do I find the path to the cert file? Can I get this info from Chrome or IE when viewing the web page? Or am I missing something even more basic?

brent5000
  • 973
  • 2
  • 8
  • 11

2 Answers2

11

The cert parameter is for client-side authentication. If you wanted to prove your identity to the server. If this was the problem you would get an error on the server.

What you need is server-side authentication. The server has to prove it's identity. As your are connecting to an internal server requests doesn't have this server certificate in it's supplied bundle and therefore can't confirm the servers identity. You have to supply requests with your internal CA-bundle. To do this you have to extract it from your browser first.

From the docs:

You can also pass "verify" the path to a "CA_BUNDLE" file for private certs.
You can also set the "REQUESTS_CA_BUNDLE" environment variable.

Chrome (short version):

  • Put this in your URL-bar chrome://settings/certificates
  • Choose tab "Authorities"
  • Find your internal CA and click export
  • Best format is "Base64 encoded certificate chain"
  • save to a location where you will find it again
  • now you can use `request.get(url, verify=)

You can also visit the certificate manager by:

(Steps for chrome, quite similar for other browsers)

  • Go to settings
  • Click "Show advanced settings" at the bottom
  • HTTPS/SSL -> "Manage Certificates"
  • See above
t-8ch
  • 2,583
  • 14
  • 18
  • 1
    Thanks, I was able to export a certificate with these instructions. However, when I passed the .cer to requests.get('https://...', verify='/path/to/.ces', I get the error: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed. It seems requests doesn't like my specific certificate, but you answered my question, which is much appreciated. – brent5000 Feb 20 '13 at 06:53
  • @brent5000 Another way is by clicking the ssl button next to your url bar. This let's you see the certificate chain of the current site. Then export the certificate at the top and try again. – t-8ch Feb 20 '13 at 19:28
  • What happens if this doesnt work off the Chrome browser? I tried doing what @t-8ch suggested using firefox and I wasnt able to export the certificate. – gerl Oct 20 '17 at 20:38
  • There is no "Base64 encoded certificate chain" or any other chain export options. I only have "Base-64 encoded X.509 (.CER)". Does this mean I cannot export the whole chain? – cowlinator Jul 11 '19 at 19:19
0

Make sure when you export the crt, to select in the file type save as dropdown "export with chain" - so that it will have all three certs in one. That was my issue.