Reputation: 3165
I am writing a program where I am trying to convert the certs, which is of pem format into PBES1
private key (the one with -----BEGIN ENCRYPTED PRIVATE KEY-----
and -----END ENCRYPTED PRIVATE KEY-----
header and footer.)
Below is the code I wrote. I am specific about the encryption algorithm used here for compatibility reasons. I was initially trying to use utf-8
encoding, but it gave me
UnicodeDecodeError: 'utf-8' codec can't decode »(,¾æ0x82 in position 1: invalid start byte
hence I changed it to latin-1
, but please correct me if I am wrong here.
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.serialization import PrivateFormat, pkcs12
from cryptography import x509
from cryptography.hazmat.backends import default_backend
def get_CN(crt_subject: x509.Name) -> str:
return next(attr.value for attr in crt_subject if attr.oid == x509.NameOID.COMMON_NAME)
def pkcs12_pbes1(password: str, pkey, clcert, cacerts: list[x509.Certificate]) -> bytes:
encryption_algorithm = (
PrivateFormat.PKCS12.encryption_builder()
.kdf_rounds(30)
.key_cert_algorithm(pkcs12.PBES.PBESv1SHA1And3KeyTripleDESCBC)
.hmac_hash(hashes.SHA256())
.build(password.encode("latin-1"))
)
return pkcs12.serialize_key_and_certificates(
name=get_CN(clcert.subject).encode("latin-1"),
key=pkey,
cert=clcert,
cas=cacerts,
encryption_algorithm=encryption_algorithm,
)
def load_ec_private_key_from_pem(file_path):
try:
with open(file_path, 'rb') as pem_file:
pem_data = pem_file.read()
private_key = serialization.load_pem_private_key(
pem_data,
password=None, # Assuming the private key is not password-protected
backend=default_backend()
)
return private_key
except Exception as e:
print("Error:", e)
return None
def read_pem_file(file_path):
try:
with open(file_path, 'rb') as pem_file:
pem_data = pem_file.read()
p_cert = x509.load_pem_x509_certificate(pem_data)
return p_cert
except FileNotFoundError:
print(f"Error: File '{file_path}' not found.")
return None
p_cert = read_pem_file('test_cert.pem')
p_key = load_ec_private_key_from_pem('test_key.pem')
p_ca = read_pem_file('test_ca.pem')
pbes1_pem = pkcs12_pbes1("somepasswd", p_key, p_cert, [p_ca])
print(pbes1_pem.decode('latin-1'))
Upon testing, I am able to read my test cert, key and ca from the file and the pbes1_pem
seems to be a binary array in encrypted form. However, I fail to write it to another file of encrypted private key pem
format like below
-----BEGIN ENCRYPTED PRIVATE KEY-----
data
-----END ENCRYPTED PRIVATE KEY-----
I was going through the hazmat
documentation and I couldn't find a helper function that could convert the encrypted binary array into the above mentioned specified format. Is this the part where I need to base64 encode the data myself and add it within those header and footer manually, or is there a helper function that I'm missing? Any help is appreciated.
Thanks.
Upvotes: 1
Views: 134