Python p12 to pem - python

I am trying to understand about openssl and certificates and also Python.
So I have this .cert.p12 file. I would like to convert it to .pem format.
I use
openssl -in input.cert.p12 -out output.pem -nodes
This creates the pem file.
How would I do the same process in Python? Take in a p12 file and covert it to a pem format?

Try using an OpenSSL for Python library like "pyOpenSSL"
https://pyopenssl.org/en/stable/api/crypto.html#pkcs12-objects
from OpenSSL import crypto
p12 = crypto.load_pkcs12(file("push.p12", 'rb').read(), [password])
# PEM formatted private key
print crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey())
# PEM formatted certificate
print crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate())
from here.

Related

Extract public-key modulus from PrivateKey/CertificateRequest/Certificate in Python , with the same format as OpenSSL

using OpenSSL, i can extract the modulus of the public key from various objects with these commands:
openssl rsa -noout -modulus -in {KEY}
openssl req -noout -modulus -in {CSR}
openssl x509 -noout -modulus -in {CERT}
I am trying to replicate this within python, using cryptography or the pyopenssl package.
I can extract the public key from all of these objects in Python, but I can not figure out how to encode the modulus to match the OpenSSL commandline output -- which appears to be a base64 encoded version of a format that I can't figure out from the docs or source code of any of the 3 projects.
The RSAPublicNumbers class (link) in cryptography has what you are looking for. You can get it using to_cryptography_key method (link) of PKey class in pyopenssl.
from OpenSSL.crypto import load_certificate
from OpenSSL.crypto import FILETYPE_PEM
with open(certfile, 'rb') as fp:
cert = load_certificate(FILETYPE_PEM, fp.read())
# This gives you the modulus in integer form
modn = cert.get_pubkey().to_cryptography_key().public_numbers().n
# Convert it to hex
print('{:X}'.format(modn))

Urllib3 custom SSL key encryption

In Python's urllib3 under Client Certificates there is an option for key_password.
Currently, I have the key info in plaintext and I want to encrypt it before storing it on the disk.
Here is the implementation:
http = urllib3.PoolManager(
... cert_file='/path/to/your/client_cert.pem',
... cert_reqs='CERT_REQUIRED',
... key_file='/path/to/your/client.key',
... key_password='keyfile_password')
However, I have not been able to find any documentation around what kind of encryption is supported for the key.
Okay. I figured it out.
I used AES symmetric encryption to encrypt the key.
Here is the command:
# openssl rsa -aes256 -in <key-file-in-plaintext> -out <key-file-encrypted>
> openssl rsa -aes256 -in key.pem -out key.pem.encrypted
This will ask you to enter a passphrase and it'll create an RSA key for you.
You can use this passphrase and pass it to the key_password named parameter.
Disclaimer: key_password is only supported in 1.25 and above versions of urllib3

How do I use a .cer file as part of a python request

Say that I have a cer file called symantec-class3.cer, this is what I'm trying:
headers = {"content-type": "application/json"}
api_url = "https://www.someurl.com/search"
pprint.pprint(requests.post(api_url, auth=HTTPBasicAuth(username, password), verify="symantec-class3.cer", data=json.dumps(payload), headers=headers).json())
This is not liking it and spews out the following error:
requests.exceptions.SSLError: [Errno 0] _ssl.c:344: error:00000000:lib(0):func(0):reason(0)
It works fine if I turn verify False, but I'm trying to use a cert file in my local directory.
Python expect cert in PEM format.
So you should extract the public key component from the X509 certificate using the openssl x509 command.
.cer extension often means a binary DER format, so this command should extract the public key in a form that can be used by pycrypto:
openssl x509 -inform der -pubkey -noout -in you.cer >public_key.pem

Python: open with .Cer file to get public key and then perform verification

I have a .cer file containing public key. I need to use this file to verify signature signed by corresponding private key.
I have the signature and public key. I need to verify the signature.
I'm getting result as false.
Below is the code:
def verify_sign(public_key_loc, signature, data):
'''
Verifies with a public key from whom the data came that it was indeed
signed by their private key
param: public_key_loc Path to public key
param: signature String signature to be verified
return: Boolean. True if the signature is valid; False otherwise.
'''
#pdb.set_trace()
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from base64 import b64decode
try:
pub_key = open(public_key_loc, "r").read()
rsakey = RSA.importKey(pub_key)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA256.new()
# Assumes the data is base64 encoded to begin with
digest.update(b64decode(data))
if signer.verify(digest, b64decode(signature)):
return True
return False
except Exception as e:
print e
I tried to use method here to convert .cer file to .pem. How do I use a X509 certificate with PyCrypto?
Is the method used here is correct? or does python has better libraries. Because as far as i know, python does not support X.509Certificate.
Bear my english.
Appreciate any help.
Thanks.
Edit:
As of now, i'm trying to use Pycrypto.
Do i need to use any other libraries or method in the same pycrypto?
You should be able to extract the public key component from the X509 certificate using the openssl x509 command. You say that your certificate file has a .cer extension which often means a binary DER format, so this command should extract the public key in a form that can be used by pycrypto:
openssl x509 -inform der -pubkey -noout -in certificate.cer >public_key.pem
Although, it's possible that your .cer file is already in PEM format (I suspect that it is because in C# you needed to base64 decode this certificate), in which case this command should get the public key:
openssl x509 -pubkey -noout -in certificate.cer >public_key.pem
Either way you should end up with a file public_key.pem that resembles this PEM format key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8ZtNvMVc3iDc850hdWu
7LLw4CQfE4O4IKy7mv6Iu6uhHQsfRQCqSbc1Nwxq70dMudG+41cSBI2Sx7bsAby2
2seBOCCtcoXmDvyBbAetaHY4xUTXzMZKxZc+ZPRR5vB+suxW9yWCTUmYyxaY3SPx
iZHRF5dAmSbW4qIrXt+9ifIbGlMtzFBBetA9KgxVcBQB6VhJEHoLk4KL4R7tOoAQ
gs6WijTwzNfTubRQh1VUCbidQihVAOWMNVS/3SWRRrcN5V2DqOWL+4TkPK522sRD
K1t0C/i+XWjxeFu1zn3xXZlA2sruOIFQvpihbLgkrfOvjA/XESgshBhMfbXZjzC1
GwIDAQAB
-----END PUBLIC KEY-----
Now you can load this using Crypto.PublicKey.RSA.importKey().
You also should double check the encoding of data and signature; make sure that these are base64 encoded as you assume, although this is probably correct since you have it working in C#.
Other options exist:
Use good old pyOpenSSL - see module OpenSSL.crypto:
import OpenSSL
cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1,
open('certificate.cer').read())
try:
OpenSSL.crypto.verify(cert, signature, data, 'sha256')
print "Signature verified OK"
except Exception as e:
print "Signature verification failed: {}".format(e)
Use M2Crypto (Python 3 not supported):
import M2Crypto
cert = M2Crypto.X509.load_cert('certificate.cer', M2Crypto.X509.FORMAT_DER)
pubkey = cert.get_pubkey()
pubkey.reset_context('sha256')
pubkey.verify_init()
pubkey.verify_update(content)
verified = pubkey.verify_final(signature)

Validate Certificate using Python

I want to access a web service over HTTPS.
I have been given a client certificate (p12 file) in order to access it.
Previously we were using basic authentication.
Using python I am unsure how to access it.
I want to use httplib2
h = Http()
#h.add_credentials("testuser", "testpass")
#h.add_certificate(keyfile, certfile, '')
resp, content = h.request("https://example.com/webservice", "POST", xml_data)
print content
Now, I am quite new to SSL, Can I just call add_cert or somethign similar and give it the p12 file.
Do I need to convert it to a PEM file?
The answer to my question was IN my question
h.add_certificate(keyfile, certfile, '')
I had a pkcs12 file, I just needed to extract out the key and cert from the p12 file.
openssl pkcs12 -in file.p12 -out key.pem -nodes -nocerts
openssl pkcs12 -in file.p12 -out cert.pem -nodes -nokeys

Categories

Resources