Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

PEM and DER Utilities

Two top-level functions handle conversion between PEM and DER byte representations.

Free functions

SignatureReturnsDescription
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)bytesWrap 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_der always returns a list, even when only one block is present. A single-block result is accessed as result[0].
  • pem_to_der raises ValueError when 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_pem produces the standard 64-character line wrap required by RFC 7468.
  • The label argument to der_to_pem appears verbatim between the BEGIN / END markers (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.