How do/can I generate a PKCS#12 file using python and the cryptography module?
It's pretty easy using said module to generate the contents of .pem file for a private key:
keyPEMBytes = privateKey.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption())
Also easy to generate the contents of a .cer/.pem file for an associated cert:
certBytes = certificate.public_bytes(encoding=serialization.Encoding.PEM)
But I need them (and their chain) balled up on a single .p12 (PKCS12 file). Said module documents how to parse/consume PKCS12 formats, but nothing (that I can find) about how one can generate them.
My understanding of PKI stuff is hit and miss though, so maybe I'm just not searching the right keyword in the documentation?
I can create the .p12 file at the command line on Linux using
openssl pkcs12 -export -out myIdentity.p12 -inkey myPrivKey.pem -in myCert.crt -certfile myCertChain.crt
So I could just wrap calls like this with subprocess/cmd and mess with tempfiles/pipes. I was hoping to keep it all in memory/python though.
Is there a different python TLS library that I should be considering, that can do this?
This use the python module cryptography
and generate a p12 file:
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import pkcs12, PrivateFormat
common_name = "John Doe"
password = "secret"
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
)
cert = x509.load_pem_x509_certificate("cert.pem")
encryption = (
PrivateFormat.PKCS12.encryption_builder().
kdf_rounds(50000).
key_cert_algorithm(pkcs12.PBES.PBESv1SHA1And3KeyTripleDESCBC).
hmac_hash(hashes.SHA256()).build(f"{password}".encode())
)
p12 = pkcs12.serialize_key_and_certificates(
f"{common_name}".encode(), private_key, cert, None, encryption
)
with open(f"{common_name}.p12", "wb") as p12_file:
p12_file.write(p12)
You have to use PBESv1SHA1And3KeyTripleDESCBC
because the Windows and macOS certificate store only supports 3DES.