X.509 certificates, decoded field by field — chains included

An X.509 certificate is a signed statement binding a public key to a name: a subject and issuer (full distinguished names with CN, O, OU and friends, not just a domain), a serial number, a validity window, the public key itself, the signature algorithm that sealed it, and a list of extensions doing the real policy work — Subject Alternative Names that say which hostnames are covered, key usage bits, basic constraints that decide whether it may sign other certificates, key identifiers, CRL distribution points and AIA pointers to the OCSP responder and issuer certificate.

The awkward part is that certificates rarely travel alone. A TLS bundle is several PEM blocks — leaf, intermediates, sometimes a cross-signed duplicate — and the only way to know how they fit together is to match issuer names and key identifiers and check each signature. This decoder does exactly that: paste a whole fullchain.pem and it dedupes identical certificates, builds the issuer graph, verifies every link's signature cryptographically, and says so per link — while staying honest that signature verification is not trust: no root store is consulted and revocation is not checked.

Open the free Certificate Decoder — no signup, runs entirely in your browser.

How to use it

  1. Paste PEM text — one certificate, a CSR, or a whole bundle with mixed blocks — or drop a .pem, .crt, .cer, .csr or .der file onto the input.
  2. Read each block's card top to bottom: subject and issuer as RFC 4514 strings plus their ordered components, validity with a live countdown, serial in hex and decimal, signature algorithm, public key, and SHA-256 / SHA-1 fingerprints.
  3. Check the extensions table: SANs render as typed chips (DNS, email, URI, IPv4, IPv6), and basic constraints preserve the difference between pathLen 0 and no constraint at all.
  4. When two or more certificates are present, open the chain section at the top: blocks are ordered leaf-first and every link shows whether the signature verifies, with cross-signed ambiguity called out instead of guessed.
  5. Copy fingerprints, serials or the base64 SPKI pin with the per-row copy buttons, or download any block back as JSON, PEM or DER.

Why this one

  • Bundles just work: mixed PEM pastes (certs, CSRs, stray text) decode block by block, identical duplicates are flagged, and private key blocks are detected and skipped without ever being read.
  • Honest chain verification: every issuer link is checked with WebCrypto and labeled 'signature verifies' — never 'trusted' — with a visible note that no root store or revocation check is involved.
  • Real-world DN handling: repeated OUs, DC components, emailAddress attributes and unknown OIDs render as an ordered list, plus a proper RFC 4514 string for copying into configs.
  • Edge cases done right: signed serial numbers (negative ones exist), RSA-PSS parameters, v1 certificates with no extensions field, and the RFC 5280 'no well-defined expiry' date all display correctly instead of as nonsense.

Frequently asked questions

Is it safe to paste certificates or CSRs here?

Yes — both are public documents by design, and the decoding runs locally in your browser. The one thing that must never be pasted anywhere is a private key; if one slips into your paste, the tool detects the block, skips it, and shows a warning without reading its contents.

What is the difference between the CN and the SANs?

The Common Name is a single attribute of the subject distinguished name — a legacy place for the hostname. Browsers have ignored it for years and only honor Subject Alternative Names, which is why a certificate can say CN=example.com and still be invalid for www.example.com when the SAN list doesn't include it. Always check the SAN chips.

Why does the chain say 'signature verifies' instead of 'valid'?

Because that is all that was checked: each certificate's signature mathematically matches its issuer's public key. Trust is a separate question — whether any of these keys chains up to a root your browser or OS trusts, and whether a certificate was revoked (CRL/OCSP). Neither is evaluated here, and the tool says so explicitly next to the chain.

My certificate shows 'not present' under extensions — is it broken?

It is a v1 certificate, which predates the extensions field entirely — common for old roots. That is different from an empty extension list: a v3 certificate always has the field, even when empty, and the decoder distinguishes the two instead of guessing 'CA: false' for a missing Basic Constraints.