A certificate is a small binary database wearing a Base64 coat, and most of the questions it answers are urgent ones: does the SAN cover the new subdomain, when exactly does it expire, which key is in it, did the CA include the right chain. This page explains what the decoder shows, field by field, and where each value tends to bite.

What the decoder reads

Paste anything that contains certificates: a single -----BEGIN CERTIFICATE----- block, a fullchain.pem with several, bare Base64 without the marker lines, or drop a file. Binary DER (the usual content of .cer and .der files) is recognised by its first byte and converted to PEM straight into the input, so decoding a Windows-exported certificate also hands you its PEM form for free.

Every certificate found becomes its own card: subject and issuer, validity with a live days-to-expiry countdown, key type and size, the full SAN list, SHA-256 and SHA-1 fingerprints, the SPKI hash and an extensions table. All of it is computed in this tab. That matters more here than on most tools, because certificate files live in directories next to private keys, and one wrong cat pastes the key instead of the cert. This decoder refuses PRIVATE KEY blocks without parsing them and says so, but the safer habit is a tool that never uploads in the first place.

Reading the summary card

The badge row answers the triage questions first. The validity badge is green while the certificate has more than 30 days left, amber at 30 days or fewer, and red once it is expired or not yet valid. "Not yet valid" deserves its amber: a notBefore in the future almost always means a machine with a wrong clock, either the client that is complaining or the box that just issued the certificate.

The countdown is calendar arithmetic on notAfter, the same number your monitoring should be watching. With public certificates capped at 200 days of lifetime since March 2026 (and 47 days from 2029), renewal is no longer an annual event you can put in a calendar; it is automation, and the countdown mostly serves to tell you whether the automation ran.

The key field compresses the SubjectPublicKeyInfo into one line: RSA 2048-bit, e=65537 or ECDSA P-256. RSA-2048 and P-256 are the two workhorses of the public web; P-256 signatures are smaller and cheaper, RSA survives everywhere including ancient clients. RSA-1024 in the key field of anything still in service is a finding, not a detail: CAs have been forbidden from issuing it since 2013.

SELF-SIGNED appears when issuer and subject are identical. On a root CA that is the expected shape. On a server certificate it explains the browser warning: no chain leads from it to anything a client trusts.

CN vs SAN

The single most useful thing to internalise about certificates: browsers match the hostname against the subjectAltName list and nothing else. The subject CN stopped being consulted in 2017, when Chrome 58 removed the fallback, and the standards had deprecated it long before. A certificate whose CN says app.example.com but whose SAN list does not is invalid for app.example.com, full stop, and Chrome will report it with the wonderfully misleading name ERR_CERT_COMMON_NAME_INVALID.

That is why the SAN list gets its own row of chips on the card rather than a line in the table, and why a certificate without any SAN shows a warning instead of an empty spot. When a hostname fails, check three things against the chips:

  • The exact name. www.example.com and example.com are different entries; most public CAs add both, internal CAs frequently forget one.
  • Wildcard scope. *.example.com covers exactly one label: app.example.com yes, a.b.example.com no, bare example.com also no. Nested subdomains need their own wildcard or their own entry.
  • IPs are their own kind. Connecting to https://10.0.0.5 requires an IP SAN entry; a DNS entry that happens to resolve there does not count. The decoder labels each chip with its kind (DNS, IP, email, URI) for exactly this distinction.

Fingerprints and serials

The SHA-256 fingerprint is the hash of the entire DER-encoded certificate, the value openssl x509 -fingerprint -sha256 prints and the fastest way to answer "is this the same certificate?" across a server, a ticket and a teammate's screenshot. One renewal, one changed byte, a completely different fingerprint. SHA-1 is shown too because plenty of UIs still display it; it remains fine as an identifier, it is only signatures that must not use SHA-1 anymore.

The SPKI hash is the more interesting one. It covers only the public key block, so it survives a renewal that reuses the key pair. Key pinning is built on it: a mobile app that pins its backend pins the SPKI hash, and the operations question "can we renew without breaking the app?" is answered by comparing the SPKI hash of the old and new certificate, which is precisely why the card shows it next to the fingerprints.

The serial number identifies the certificate within its CA, and the issuer-plus-serial pair identifies it globally. Modern serials are long random strings because the CA/Browser Forum has required at least 64 bits of CSPRNG entropy in them since 2016, a lesson from the 2008 attack that forged a CA certificate by predicting sequential MD5-signed serials. A short, tidy serial like 04 or 1000 is therefore itself a hint that you are looking at an internal or hand-rolled CA.

The extensions worth knowing

Version 3 certificates carry their machine-readable policy in extensions, defined in RFC 5280. The table on each card lists all of them, marks the critical ones, and summarises the usual suspects:

ExtensionWhat it saysWhat goes wrong
basicConstraintsWhether this certificate may sign others (CA: TRUE) and how deep a chain it may head (pathlen)CA: TRUE on a server certificate is a serious misissuance; pathlen: 0 on an intermediate forbids further intermediates below it
keyUsageCrypto-level permissions of the keyA TLS server needs Digital Signature (ECDSA and modern RSA key exchange); a CA needs Certificate Sign
extKeyUsagePurposes: serverAuth, clientAuth, codeSigning, …No serverAuth, no HTTPS: browsers reject the certificate regardless of everything else
subjectKeyIdentifier / authorityKeyIdentifierHash of this key / of the issuer's keyThe pair is how chain building matches child to parent when names are ambiguous; AKI equal to SKI is the self-signed signature
cRLDistributionPointsWhere the CA publishes revocationsMostly historical for browsers, still checked by Java and some proxies
authorityInfoAccessThe OCSP responder URL and caIssuers, a download URL for the issuing certificatecaIssuers is how Chrome quietly repairs a server that forgot its intermediate; Firefox does not, which is why "works in Chrome, fails in Firefox" usually means an incomplete chain
certificatePoliciesThe validation level as an OID2.23.140.1.2.1 is domain-validated, .2.2 organization-validated, 2.23.140.1.1 extended validation; the decoder names them
SCT listSigned Certificate Timestamps from Certificate Transparency logsChrome requires embedded or stapled SCTs for public certificates issued since 2018; a public cert without any is a red flag

The critical column is worth a glance when a certificate behaves oddly in one client only: a client that does not understand a critical extension must reject the certificate, and exotic critical extensions from internal CAs are a recurring source of "works everywhere except X".

Pasting a whole chain

Paste a fullchain.pem, or several PEM blocks from anywhere, and the decoder works out who signed whom by matching each issuer against the other subjects. Each card gets a role badge (LEAF, INTERMEDIATE CA, ROOT CA) and a chain line shows the resulting path, flagging any certificate whose issuer is not in the paste.

Two honest limits. The matching is by name, not by cryptography: the decoder confirms that the names link up, not that the signatures verify. And it says nothing about whether a client will trust the root. Both questions need the signatures checked, which is a different job from reading the fields. Our experience is that the name-level view already catches the everyday mistakes, wrong intermediate, chain in the wrong file, staging cert in the production bundle, before the cryptographic question even comes up.

The openssl equivalents

Everything the decoder shows has a command-line equivalent, and knowing both is the comfortable position: the tool for reading and sharing, the commands for scripts and CI.

TaskCommand
Full dump of a fileopenssl x509 -in cert.pem -text -noout
Same, for binary DERopenssl x509 -in cert.cer -inform der -text -noout
SHA-256 fingerprintopenssl x509 -in cert.pem -noout -fingerprint -sha256
Expiry date onlyopenssl x509 -in cert.pem -noout -enddate
SAN list onlyopenssl x509 -in cert.pem -noout -ext subjectAltName
Certificate of a live serverecho | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -text -noout

Two gotchas from running these on real machines. macOS ships LibreSSL under the openssl name, and its older versions lack -ext; the -text dump always works. And s_client without -servername skips SNI, so multi-tenant servers hand you their default certificate and you spend ten minutes debugging the wrong cert. When the output of any of these commands needs to be read by a human under time pressure, pasting it here is the faster path: the fields are labelled, the countdown is computed, and the SAN chips beat scanning a comma-separated line.

If what you actually hold is a certificate signing request rather than a certificate, the decoder says so instead of guessing: a CSR carries a subject and a public key, but no issuer, no validity and no CA signature, so there is no expiry to count down and no chain to assemble. Keystores in PFX/P12 form have to come apart first, with openssl pkcs12 -in store.pfx -clcerts -nokeys -out cert.pem, and the PEM that falls out is what you paste here.

Reading a certificate

How do I view the contents of a .crt or .pem certificate file?

openssl x509 -in certificate.crt -text -noout prints everything: subject, issuer, validity, key, extensions. If the file is binary DER rather than Base64 text, add -inform der. On Windows without OpenSSL, renaming to .cer and double-clicking opens the system certificate viewer, which shows the same fields with less detail. A browser-based decoder like this one is the third route: it reads PEM and DER, needs no install, and parses the file locally in the tab.

What is the difference between .crt, .cer, .pem and .der files?

Only two encodings exist behind those four extensions: PEM, which is Base64 text between -----BEGIN CERTIFICATE----- markers, and DER, which is the same bytes in binary. The extension is a convention, not a format: .crt and .cer can contain either encoding, .pem is almost always PEM text, .der is almost always binary. The reliable test is opening the file: readable Base64 with BEGIN lines is PEM, anything that looks like garbage is DER. This decoder accepts both and shows a dropped DER file as PEM, and the PEM to DER converter handles conversion in both directions.

Does the Common Name (CN) still matter in TLS certificates?

Not for hostname matching. Chrome stopped reading the CN in version 58 (2017), Firefox and Safari followed, and RFC 6125 had recommended SAN-only matching long before. The CN survives as a display label in certificate viewers and as the identity field in private PKI setups, but a public TLS certificate is validated purely against the subjectAltName list. CAs still copy the primary hostname into the CN out of tradition, which is exactly why the mismatch confuses people when the SAN list is the thing that is wrong.

Why do I get ERR_CERT_COMMON_NAME_INVALID when the CN matches the domain?

Because the browser never checked the CN: the error name is historical. Chrome raises NET::ERR_CERT_COMMON_NAME_INVALID whenever the hostname is missing from the subjectAltName extension, even if the CN matches perfectly. Decode the certificate and look at the SAN list: the hostname you are visiting has to be there verbatim or be covered by a wildcard entry. A wildcard only covers one label (*.example.com matches app.example.com but not a.b.example.com and not the bare example.com), which is the second most common cause after a plainly missing entry.

How do I get the SHA-256 fingerprint of a certificate?

openssl x509 -in cert.pem -noout -fingerprint -sha256 prints it as colon-separated hex pairs. The fingerprint is the SHA-256 hash of the whole DER-encoded certificate, so it changes with every renewal even when the key stays the same. It identifies exactly one certificate, which makes it the value to compare when you want to confirm that the file on the server, the file in the ticket and the file in your monitoring are the same object.

What is the difference between a certificate fingerprint and an SPKI hash?

The fingerprint hashes the entire certificate, the SPKI hash covers only the SubjectPublicKeyInfo block, meaning the public key plus its algorithm. The practical difference is lifetime: a renewal that reuses the key pair produces a new fingerprint but the same SPKI hash. That is why key pinning (HPKP historically, certificate pinning in mobile apps today) pins the SPKI hash, usually Base64-encoded as in openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64. Pinning a fingerprint would break at the first renewal.

How can I check when an SSL certificate expires from the command line?

For a file: openssl x509 -in cert.pem -noout -enddate. For a live server: echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate. The -servername flag matters, because without SNI many servers present a different default certificate and you check the wrong one. For monitoring, the same s_client pipe feeds into openssl x509 -checkend 2592000, which exits non-zero when the certificate dies within 30 days.

What are Key Usage and Extended Key Usage in a certificate?

Key Usage restricts what the key itself may do at the crypto level: digitalSignature and keyEncipherment for a TLS server, keyCertSign and cRLSign for a CA. Extended Key Usage restricts the purposes: serverAuth for TLS servers, clientAuth for mutual TLS clients, codeSigning, emailProtection. Both are enforced. A certificate without serverAuth in its EKU is rejected by every browser regardless of hostname and validity, which is a classic failure when an internal CA template meant for client certificates gets used for a server.

What is the maximum validity period for a TLS certificate?

For certificates issued since 15 March 2026 it is 200 days; before that it was 398 days, the limit in force since September 2020. The CA/Browser Forum ballot SC-081 fixed the rest of the schedule: 100 days for certificates issued from March 2027, and 47 days from March 2029. Certificates from public CAs cannot exceed the cap because browsers reject longer ones outright. Only private, internal CAs can still issue multi-year certificates, and only for clients that trust that CA.

Is it safe to paste a certificate into an online SSL decoder?

The certificate itself is public material: the server hands it to every client that connects, so pasting it reveals nothing new. The real risk sits next to it, because cert directories usually also hold the private key, and pasting the wrong file into a tool that uploads is how keys leak. Prefer a decoder that parses locally: this one runs entirely in the tab, nothing is sent anywhere, and if a PRIVATE KEY block lands in the paste it is refused unparsed with a warning rather than processed.

How do I decode a certificate in Python or Node.js?

Python: from cryptography import x509, then x509.load_pem_x509_certificate(pem_bytes) gives an object with subject, not_valid_after_utc, and extensions; use load_der_x509_certificate for binary files. Node.js has it built in since v15.6: new crypto.X509Certificate(pem) exposes subject, validTo, subjectAltName and fingerprint256 without any dependency. Both parse locally and are the right tool the moment decoding happens in a loop or a CI check rather than once by hand.

How can I tell if a certificate is self-signed?

Issuer and subject are identical, and when both key identifier extensions are present, the Authority Key Identifier equals the Subject Key Identifier. That is the whole test this decoder applies for its SELF-SIGNED badge. Note what it does not mean: every root CA certificate is self-signed by construction, so the badge is only a problem on a certificate that is supposed to be publicly trusted for a website, where it produces ERR_CERT_AUTHORITY_INVALID for every visitor.

Are certificate serial numbers unique?

Unique per CA, not globally: the pair of issuer name and serial number identifies a certificate, the serial alone does not. Since 2016 the CA/Browser Forum requires public CAs to put at least 64 bits of CSPRNG output into the serial, a consequence of the 2008 MD5 collision attack that exploited predictable sequential serials. That is why modern serials are long random hex strings rather than small counters, and why comparing serials is a fine way to check whether two files are the same certificate from the same CA.