from cryptography import x509from cryptography.hazmat.primitives import serializationfrom cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat def cert_pem_to_der(pem: bytes) -> bytes: return x509.load_pem_x509_certificate(pem).public_bytes(Encoding.DER) def cert_der_to_pem(der: bytes) -> bytes: return x509.load_der_x509_certificate(der).public_bytes(Encoding.PEM) def key_pem_to_der(pem: bytes, password: bytes | None = None) -> bytes: key = serialization.load_pem_private_key(pem, password=password) return key.private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption()) def key_der_to_pem(der: bytes, password: bytes | None = None) -> bytes: key = serialization.load_der_private_key(der, password=password) return key.private_bytes(Encoding.PEM, PrivateFormat.PKCS8, NoEncryption()) How it works
x509.load_pem_x509_certificate(pem).public_bytes(Encoding.DER)returns the certificate's DER (563 bytes here);load_der_x509_certificate(der).public_bytes(Encoding.PEM)goes back, identical to the original file.- For keys,
load_pem_private_key/load_der_private_keyread any supported key;private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption())writes PKCS#8 DER (138 bytes for this P-256 key). - Pass
password=to read an encrypted key, andBestAvailableEncryption(b"…")instead ofNoEncryption()to write one. - The run checks the DER with OpenSSL (
openssl x509 -inform DER) as well, so the bytes are what other tools expect.
Gotchas
PrivateFormat.TraditionalOpenSSLwrites an EC key as SEC1 (121 bytes,BEGIN EC PRIVATE KEYin PEM), not PKCS#8 — a different byte string that many importers reject. Ask forPrivateFormat.PKCS8explicitly.- DER carries no label, so the loader must match the content:
load_der_private_keyon a certificate's DER raisesValueError: Could not deserialize key data…. - DER holds one object per file; for a PEM bundle,
x509.load_pem_x509_certificates(plural) returns every certificate (2 in the run), and each gets its own DER file.
Related recipes
- How to convert a certificate and a private key between PEM and DER with OpenSSL
- How to convert a certificate and a private key between PEM and DER in Go
- How to convert a certificate and a private key between PEM and DER in Node.js
- How to export a public key as PEM in Python
- How to decode an X.509 certificate in Python