PEM and DER Utilities
Two top-level functions handle conversion between PEM and DER byte representations.
Free functions
| Signature | Returns | Description |
|---|---|---|
pem_to_der(data: bytes) | list[bytes] | Decode one or more PEM blocks to DER. Always returns a list (one entry per block); no block present → ValueError. |
der_to_pem(der: bytes, label: str) | bytes | Wrap DER bytes in a -----BEGIN {label}----- / -----END {label}----- block. |
Usage
import synta
# Decode a PEM file with one or more certificates
pem_data = open("bundle.pem", "rb").read()
der_list = synta.pem_to_der(pem_data) # list[bytes] — one entry per PEM block
for der in der_list:
cert = synta.Certificate.from_der(der)
print(cert.subject)
# Single-block PEM (typical for one certificate)
der_list = synta.pem_to_der(open("cert.pem", "rb").read())
cert = synta.Certificate.from_der(der_list[0])
# Wrap DER bytes back into PEM
der = cert.to_der()
pem = synta.der_to_pem(der, "CERTIFICATE")
open("cert.pem", "wb").write(pem)
# Private key PEM
key_der = open("key.der", "rb").read()
pem = synta.der_to_pem(key_der, "PRIVATE KEY")
# Empty PEM raises ValueError
try:
synta.pem_to_der(b"not pem")
except ValueError as e:
print(f"No PEM block found: {e}")
Notes
pem_to_deralways returns alist, even when only one block is present. A single-block result is accessed asresult[0].pem_to_derraisesValueErrorwhen no PEM block is found. It does not silently return an empty list.- Malformed base64 inside a PEM block is also rejected with
ValueError. der_to_pemproduces the standard 64-character line wrap required by RFC 7468.- The
labelargument toder_to_pemappears verbatim between theBEGIN/ENDmarkers (e.g."CERTIFICATE","PRIVATE KEY","CERTIFICATE REQUEST").
See also PKCS Loaders for format-agnostic reading of PEM bundles, PKCS#7 files, and PKCS#12 archives.