ecdsa.com

Export public key PEM · Python

How to export a public key as PEM in Python

In Python's cryptography package, exporting a public key as PEM is a method chain: public_key() derives the public half from the private key, and public_bytes serializes it. The two enum arguments — PEM encoding, SubjectPublicKeyInfo format — produce the standard BEGIN PUBLIC KEY file.

Tested with Python 3.14 and cryptography 50.0.

Same recipe in:Node.jsPythonGoOpenSSLWebCrypto
export_pub.py — private PEM in, public PEM out
from cryptography.hazmat.primitives.serialization import (
Encoding,
PublicFormat,
load_pem_private_key,
)
 
private_key = load_pem_private_key(open("key.pem", "rb").read(), password=None)
public_key = private_key.public_key()
 
pem = public_key.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
open("pub.pem", "wb").write(pem)
print(pem.decode(), end="") # -----BEGIN PUBLIC KEY-----
already holding a public key object? same call
from cryptography.hazmat.primitives.serialization import load_pem_public_key
 
public_key = load_pem_public_key(open("pub.pem", "rb").read())
der = public_key.public_bytes(Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
print(len(der), "bytes of SPKI DER") # 91 for P-256

How it works

  1. private_key.public_key() computes the public point — no key material needs to be stored twice.
  2. Encoding.PEM + PublicFormat.SubjectPublicKeyInfo is the portable pairing; Encoding.DER gives the same structure in binary.
  3. PublicFormat.UncompressedPoint (with Encoding.X962) exists for protocols that want the bare 04‖x‖y point rather than a container.

Gotchas

  • public_bytes requires both arguments — there are no defaults, and mismatched pairs (PEM + UncompressedPoint) raise ValueError by design.
  • An uncompressed point (65 bytes on P-256) is not a PEM body: wrapping raw point bytes in BEGIN/END lines produces a file nothing can parse. The SPKI container adds the algorithm and curve identifiers.
  • For SSH-format keys (ecdsa-sha2-nistp256 AAAA…) use Encoding.OpenSSH + PublicFormat.OpenSSH — SPKI PEM and authorized_keys lines are different serializations of the same key.

Related recipes