What is in a PEM file?
Published: 2026-09-05
How PEM wraps DER: BEGIN/END labels, Base64 payloads, common key and certificate types, multi-block pastes, and how to inspect them locally without uploading secrets.
PEM (Privacy-Enhanced Mail, in name only today) is the text format you usually see when someone says “paste your certificate” or “here’s the private key.” It is not a separate crypto algorithm. It is a labeled Base64 envelope around binary DER (ASN.1-encoded) bytes. The same key or cert can live as a .der file (raw binary) or a .pem / .crt / .key file (text PEM)—the cryptographic payload is the same; only the wrapping differs.
This guide walks through what sits between the BEGIN and END lines, which labels mean what, how multi-block pastes work, and how to inspect PEM in the browser without uploading keys or certs.
Anatomy of one PEM block
A typical block looks like this:
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIU…
(more Base64 lines)
-----END CERTIFICATE-----
| Piece | Role |
|---|---|
-----BEGIN …----- |
Starts the block; the words after BEGIN are the label |
| Base64 body | Encoded DER bytes, usually wrapped at ~64 characters per line |
-----END …----- |
Closes the block; label should match BEGIN |
| Optional header lines | Rare lines with a colon (e.g. legacy Proc-Type:) sit above the Base64; parsers skip them |
Decode the Base64 and you get DER: opaque binary until an ASN.1 / X.509 library parses it. Tools that only “decode PEM” often stop at: label, continuous Base64, and decoded byte length—enough to confirm the paste is well-formed before you feed it to OpenSSL, Web Crypto, or a TLS stack.
Common BEGIN labels
The label tells you what kind of DER blob you have. It does not encrypt or protect the contents by itself.
| Label | Typical contents |
|---|---|
CERTIFICATE |
X.509 certificate (leaf, intermediate, or root) |
CERTIFICATE REQUEST |
PKCS#10 CSR (certificate signing request) |
PRIVATE KEY |
PKCS#8 private key (algorithm + key material) |
PUBLIC KEY |
SPKI (SubjectPublicKeyInfo) public key |
RSA PRIVATE KEY |
Older PKCS#1 RSA-only private encoding |
ENCRYPTED PRIVATE KEY |
Password-protected PKCS#8 (still PEM text; ciphertext inside) |
EC PRIVATE KEY |
EC private key in SEC1 / similar traditional form |
Modern exports from Web Crypto and many generators use PRIVATE KEY (PKCS#8) and PUBLIC KEY (SPKI). That is what LocalTools’ RSA Key Generator emits. Older stacks and some openssl defaults still produce RSA PRIVATE KEY; importers that only accept PKCS#8 will reject those until you convert.
For how modulus size and OAEP/PSS relate to those key PEMs, see RSA keypairs: sizes and PEM. For building CSRs and self-signed certs around similar keys, see PKI Certificate Studio.
Base64 length vs DER size
Base64 expands binary by about 4/3. Rough check:
- DER bytes ≈
(Base64 character count without padding) × 3 / 4 - A short hex prefix of the decoded bytes is a quick sanity check that Base64 decoded cleanly (you should see recognizable ASN.1 patterns like a leading
30for a SEQUENCE—not a requirement to memorize).
If Base64 is truncated, has spaces where they do not belong, or was double-encoded, decode fails or the DER length looks wrong for the label (e.g. a “certificate” that is only a few dozen bytes).
Multiple blocks in one paste
TLS and ops workflows often concatenate PEM:
- Leaf certificate
- Intermediate(s)
- Sometimes a private key in the same file (common in some app server configs—convenient, risky if the file is shared)
A PEM-aware splitter finds each BEGIN/END pair in order. Labels can differ between blocks in the same paste. Mismatched BEGIN vs END on a single block (typo or corrupt copy) is a red flag even if Base64 still decodes.
What PEM is not
- Not encryption by default —
BEGIN PRIVATE KEYis usually plaintext key material in Base64. Anyone who can read the file can use the key. OnlyENCRYPTED PRIVATE KEY(or an external passphrase wrapper) adds confidentiality. - Not a full ASN.1 viewer — reading labels and DER length is inspection; validating SANs, chains, or key usages needs a certificate/PKI tool.
- Not OpenSSH’s special formats —
-----BEGIN OPENSSH PRIVATE KEY-----is related in spirit but a different body format; treat it separately from PKCS#8 / X.509 PEM.
Inspect PEM without uploading it
Private keys and production certificates are sensitive. Prefer local parsing over paste-into-random-website workflows:
- Open the file or clipboard paste in a local tool or CLI (
openssl, etc.). - Confirm labels and that Base64 decodes to a plausible DER size.
- Clear private key material from the tab when finished; never commit production private PEM to git.
LocalTools’ PEM Decoder runs entirely in-tab: paste one or more RFC 7468–style blocks, see each BEGIN/END label, continuous Base64 (headers stripped), decoded DER byte length, and a short hex preview. Optional colon header lines are skipped. Nothing is uploaded.
Common pitfalls
- Assuming
.pemmeans “certificate” — the extension is conventional; the label decides whether it is a key, cert, or CSR. - PKCS#1 vs PKCS#8 —
RSA PRIVATE KEYvsPRIVATE KEYbreaks naive importers; convert or pick the dialect your API documents. - Broken line wrapping — email or chat clients that insert spaces or soft line breaks corrupt Base64.
- Label mismatch —
BEGIN CERTIFICATEpaired withEND PRIVATE KEYmeans a bad paste, not a fancy hybrid format. - Treating PEM decode as “safe to share” — decoding locally does not make the private key non-secret; rotate if it leaked.
Try it in the browser
Use the PEM Decoder to:
- Paste a certificate or a keypair PEM from the RSA Key Generator (or any local
.pemfile). - Confirm each block’s label, Base64 length, and DER size; copy the raw Base64 if another tool needs headers stripped.
- Paste a multi-block chain and verify blocks appear in order—then clear any private key from the page.
Related reading: RSA keypairs: sizes and PEM for key labels and sizes, Why “local only” matters for developer tools for the privacy model, and AES-GCM basics (nonce, tag, AAD) when PEM wraps keys used in hybrid encryption workflows.