Python3 reques with cert and key "verified fail" - python

I'm trying to request data from endpoints, I can do that with curl -k --key a-key.pem --cert a.pem https://<endpoint>
But when I using python3 to do that, I failed every time
Examples:
With curl:
root#control-plane-0:~# curl -k --key /etc/kubernetes/a-key.pem --cert /etc/kubernetes/a.pem https://127.0.0.1:6443/api/
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.31.2:6443"
}
]
}
With python:
(code):
from flask import Flask, render_template
import requests
from ast import literal_eval
app = Flask(__name__)
#app.route('/metrics')
def metrics():
data = requests.get("https://127.0.0.1:6443/api/, cert=('/etc/kubernetes/a.pem', '/etc/kubernetes/a-key.pem'))
print(data)
return data
if __name__ == '__main__':
app.run(host='0.0.0.0',port="5001", debug=True)
Result:
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 514, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='127.0.0.1', port=6443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1121)')))
Are there any problems with requests libs ?
I can't find a way to make it work

Have you got your certificates verified using
openssl verify -CAfile your-cert.pm
I got the same Problem and solved by using full-chain certificates.please see your certificate contains fullchain(root,intermediate).
And you can try like
import requests
test=request.get("url",verify="certificate-with-path")

Related

Python, how to send a request with attached certificates?

I have 3 files/certificates:
I need to send a POST request to the bank attaching all these 3 certificates to these url:
This is my code:
import requests
url = 'https://ecomm.pashabank.az:18443/ecomm2/MerchantHandler'
data = { # for example
"command": "v",
"amount": "1",
"currency": "932",
"client_ip_addr": "167.172.184.123",
"msg_type": "SMS"
}
cert_file = "certificate.0025598.der"
key_file = "certificate.0025598.pem"
psroot = "PSroot.pem"
certs = (cert_file, key_file, psroot)
response = requests.post(url, cert=certs)
But it doesn't work, giving this error:
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='ecomm.pashabank.az', port=18443): Max retries exceeded with url: /ecomm2/MerchantHandler (Caused by SSLError(SSLError(9, '[SSL] PEM lib (_ssl.c:4027)')))
Maybe I am attaching certificates incorrectly? Please help!
I wanted to send the request via Postman, but I also failed there. Could you explain how to do that?
make sure your cert is format in pem.
pass the filename to param cert (or file path, which means your pem file is in current directory)
https://requests.readthedocs.io/en/latest/user/advanced/?highlight=cert#client-side-certificates

Request not working for Python AWS Lambda

on a AWS Lambda function, I have a simple HTTP Request
import requests
def lambda_handler(event, context):
request_headers = {
'X-API-KEY': 'somekey',
'Content-Type':content,
'Host':'somehost',
}
resp = requests.get(some_url_here, headers=request_headers)
api_response = resp.json()
If I set the request requests.get(some_url_here, headers=request_headers, verify=False) I got no issues with the code and it works perfectly, but when I removed it it yields
Error encountered: HTTPSConnectionPool(host='x.xxx.xxx.xx', port=443): Max retries exceeded with url:some_url_here (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1124)')))
how to fix this issue?

Client certificate works in curl but not in Python

Using curl I can connect to a server that needs specific certificate.
curl -E ./file.crt.pem --key ./file.key.pem -k https://server.url
curl version: 7.29.0
But when using Python's requests library, I get an error:
import requests
cert_file_path = "file.crt.pem"
key_file_path = "file.key.pem"
cert = (cert_file_path, key_file_path)
url = 'https://server.url'
r = requests.post(url, cert=cert, verify=False)
Error:
SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_read_bytes', 'tlsv1 alert unknown ca')])"))
Python version: v3.7
What am I missing?
A comment on this answer helped me figure this out.
Update your code as such:
import requests
cert_file_path = "file.crt.pem"
key_file_path = "file.key.pem"
cert = (cert_file_path, key_file_path)
url = 'https://server.url'
r = requests.post(url, cert=cert, verify="path/to/ca_public_keys.pem") # replace with your file
I'm assuming you're using a self-signed certificate, so you need to specify the .pem file containing the public certificates of the CA that issued your self-signed certificate. Make sure to include the intermediate certificates, otherwise the requests library will throw the tlsv1 alert unknown ca error.
You can check the issuer of your client certificate by typing openssl x509 -noout -in file.crt.pem -issuer in a terminal.
Request module checks environmental variable REQUESTS_CA_BUNDLE for cert file. So just do this
export REQUESTS_CA_BUNDLE=/absolute/path/to/your/file.crt.pem
Your python code will simply be:
import requests
url = 'https://server.url'
r = requests.post(url)
print(r.text)

python Requests SSL ERROR (certificate verify failed)

I have generated following self-signed certificates for my server and client.
I have created ca.crt & ca.key. Using ca.crt & ca.key, I have created server.crt, server.key for server and client.crt, client.key for client respectively.
I am using python requests library as client. Below is the code snippet:
import json
import requests
cert = ("/home/tests/certs/client.crt",
"/home/tests/certs/client.key")
class TestCart():
def test_cart(self, **kwargs):
url = "https://192.168.X.Y/cart"
cart_data = {
'id': kwargs.get('id'),
'items': kwargs.get('items')
}
req_data = json.dumps(cart_data)
resp = requests.post(url,
data=req_data,
verify="/home/certs/ca.cert",
cert=cert)
print resp.text
if __name__ == '__main__':
t_cart = TestCart()
data = {'id': 'ba396e79-0f0f-4952-a931-5a528c9ff72c', 'items': []}
t_cart.test_cart(**data)
This gives exception:
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.X.Y',
port=443): Max retries exceeded with url: /cart (Caused by
SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify
failed (_ssl.c:590)'),))
If I use verify=False, code works, but I want to verify. What should be the value of verify in my request ?
It is highly recommended to have a deeper look at the excellent documentation for requests. It has a special chapter about SSL Cert Validation which explains:
You can pass verify the path to a CA_BUNDLE file or directory with certificates of trusted CAs:
>>> requests.get('https://github.com', verify='/path/to/certfile')
Assuming that your server certificate was signed by your ca.crt you should use this for the verify parameter.
EDIT: based on the discussion it looks like that CA and server certificate used the same subject. This means that the certificate validation assumes that this is a self-signed certificate which thus results in an certificate validation error.

Python how to make curl requests

I need help making the following Curl request in Python:
curl --data "username=USERNAME&password=PASSWORD" --header "Authorization: Basic Y2xvdWQtYXBp" -X POST "https://ApiCallUrl/auth/token?grant_type=password" --insecure
I have the following code:
url = 'https://fakepath'
data = "username=velocity_169234&password=velocity_69234"
header = {'Authorization': b'Basic' + b64encode(('cloud-api').encode('utf-8'))}
data = urlencode(dict(username='USERNAME',password='PASSWORD')).encode('ascii')
response = urlopen(Request(url, data, header))
print(response.info())
How do I add the --insecure flag?
I am getting this error
raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)>
curl
-k, --insecure
(SSL) This option explicitly allows curl to perform "insecure" SSL connections and transfers.
All SSL connections are attempted to be made secure by using the CA certificate bundle installed by default.
All connections considered "insecure" will fail unless -k/--insecure is used.
requests
Requests can also ignore verifying the SSL certificate if you set verify to False:
requests.get('https://kennethreitz.org', verify=False)
<Response [200]>
By default, verify is set to True. Option verify only applies to host certs.
urlopen don't have such a parameter.
Note: Disable Certificate Verification is a Security Risk!

Categories