Reputation: 61
I am using request library for automating APIs/microservices. I tried passing URL, certificates(path of the certificate file and key file) in get request.
After running the program, It asks for PEM pass phrase. Please refer below lines of command prompt.
>>> r = requests.get("https://foo.example.com/api/user/bill", cert=("client.crt", "client.key"))
Enter PEM pass phrase:
>>>
How to pass the passphrase programmatically in the program in order to avoid manual intervention of entering PEM passphrase in the program?
Upvotes: 6
Views: 14310
Reputation: 1280
The requests library doesn't support password-protected PEM files yet.
One option is to convert it to a pkcs12 file and use the requests-pkcs12 libary from https://pypi.org/project/requests-pkcs12/
Another option is to convert it to a pkcs12 file and then to a PEM file without password.
You can convert it as follows:
# Password protected PEM to pkcs12
openssl pkcs12 -export -out cert.p12 -in cert.pem -inkey key.pem -passin pass:supersecret -passout pass:supersecret
# pkcs12 to PEM without password
openssl pkcs12 -in cert.p12 -out cert_without_pwd.pem -nodes -password supersecret
Upvotes: 6
Reputation: 137
import requests
from urllib3.util.ssl_ import create_urllib3_context
from requests.adapters import HTTPAdapter
cert_path = "path/to/certfile.crt"
private_key_path = "path/to/private_certificate_file.pem"
passphrase_key = "someSecretKey"
class SSLAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context()
context.load_cert_chain(certfile=cert_path, keyfile=private_key_path, password=passphrase_key)
kwargs['ssl_context'] = context
return super().init_poolmanager(*args, **kwargs)
session = requests.Session()
session.verify = False # If you don't want to validate server's public certificate
session.mount("https://", SSLAdapter())
response = session.post(url)
print(response.json())
I was recently working on the same problem where I had an encrypted private certificate and I have to use the passphrase key to decrypt it during the rest api call in python. I just thought of sharing my code to answer this question. This code is working for me.
Upvotes: 4
Reputation: 4196
I think , you are looking for "verify
" option in request module.
Check this link
Try the following steps:
r = requests.get("https://foo.example.com/api/user/bill", cert=("client.crt", "client.key"), verify="test.pem")
Upvotes: 1
Reputation: 8813
It appears that at time of writing (August 2018), you're out of luck. There's an open issue on the requests tracker from September 2013 that addresses just this situation. There are several workarounds listed that involve using a different library, or generating new keys without a passphrase.
As far as I know currently it's not possible to specify the password for the client side certificate you're using for authentication.
This is a bit of a problem because you typically always want to password protect your .pem file which contains the private key. openssl won't even let you create one without a password.
Upvotes: 2