SSL Certificate Decoder

Decode an SSL/TLS certificate without reading openssl x509 -text output. Paste a PEM block, a whole chain, or upload a DER file, and you get the subject, SANs, expiry, key type and every extension a browser checks. A small hand-written ASN.1 reader parses it in this tab, so the certificate is never uploaded.

PEM Certificate or Chain
Decoded

Paste a certificate, or click Example Chain. A full chain (leaf, intermediates, root) is decoded one card per certificate.

1 SSL Certificate Decoder (X.509 / PEM) example

PEM input

-----BEGIN CERTIFICATE-----
MIIDSDCCAs6gAwIBAgIUPtlVi22WWaf/FmcQ2emo0iJZpS0wCgYIKoZIzj0EAwMw
...
-----END CERTIFICATE-----

Decoded (abridged)

Subject: C=US, ST=California, L=San Francisco, O=Example Shop Ltd, CN=shop.example.com
Issuer: C=US, O=Example Test CA, CN=Example Test Root R1
Serial: 3E:D9:55:8B:6D:96:59:A7:FF:16:67:10:D9:E9:A8:D2:22:59:A5:2D
Not After: 2031-09-29T10:25:21.000Z
Signature Algorithm: ecdsa-with-SHA384
Public Key: EC P-256 (prime256v1), 256 bit
Subject Alternative Name:
    DNS:shop.example.com
    DNS:*.shop.example.com
    IP:203.0.113.10
    IP:2001:db8::10

2 The fields worth checking first

Subject Alternative Name

Check the SAN list, not the CN. Browsers match the hostname against the SANs only; Chrome has ignored the subject CN for this since version 58. A hostname missing from the SANs is a mismatch error.

Not After

The expiry, in UTC. The badge on each card counts the days. Check the intermediates too: an expired intermediate breaks the chain the same way an expired leaf does.

Issuer and Authority Key ID

In a correct chain, each certificate's issuer equals the next one's subject, and its Authority Key Identifier equals the next one's Subject Key Identifier. Each card flags it when the order looks wrong.

Basic Constraints

CA:TRUE means the certificate can sign other certificates. A leaf should say CA:FALSE. pathlen:0 on an intermediate means it may only sign leaves.

3 This decoder reads certificates but does not verify them

The tool does not check the signature against the issuer's key, query revocation (CRL or OCSP), or compare anything against a trust store. A certificate that decodes cleanly here can still be rejected by a browser. For a live server, openssl s_client -connect host:443 -showcerts shows the chain the server sends, and you can paste that whole output in: the decoder ignores anything outside the BEGIN and END lines.

The decoder does not parse PKCS#7 (.p7b) or PKCS#12 (.pfx) bundles. Convert them first with openssl pkcs7 -print_certs -in bundle.p7b or openssl pkcs12 -in file.pfx -nokeys. Never paste a private key into a website, this one included. The decoder refuses to display one, but the key has already left your terminal by then.

How to use the SSL Certificate Decoder (X.509 / PEM) tool

  1. Paste one certificate or a whole chain into the left panel. Anything between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- is decoded; surrounding text is ignored.
  2. Or click Upload File and pick a .pem, .crt, .cer or .der file. Binary DER is converted to PEM in the input box so you can see what was read.
  3. Read each card on the right: subject, issuer, validity with the days-left badge, serial, signature algorithm, key type and size, then every extension, SANs included.
  4. SHA-256 and SHA-1 fingerprints at the bottom of each card are computed over the DER bytes, so they match what openssl and browsers show.
  5. Copy Result copies a plain-text summary of every certificate. Example Chain loads a leaf plus its test root; Clear empties the input.

How to read a certificate in Node.js, PHP and the shell

Node.js

const { X509Certificate } = require("node:crypto");
const fs = require("node:fs");

const cert = new X509Certificate(fs.readFileSync("cert.pem"));

console.log(cert.subject);          // "C=US\nST=California\n...\nCN=shop.example.com"
console.log(cert.issuer);
console.log(cert.subjectAltName);   // "DNS:shop.example.com, ..., IP Address:203.0.113.10, ..."
console.log(cert.validTo);          // "Sep 29 10:25:21 2031 GMT"
console.log(cert.serialNumber);     // hex, no colons
console.log(cert.fingerprint256);   // "1B:0C:6C:..."
console.log(cert.publicKey.asymmetricKeyType); // "ec" or "rsa"

const daysLeft = Math.floor((new Date(cert.validTo) - Date.now()) / 86400000);
console.log(daysLeft + " days left");

X509Certificate reads one certificate. For a chain, split the file on the END CERTIFICATE line and construct one per block.

PHP

<?php
$pem = file_get_contents('cert.pem');
$info = openssl_x509_parse($pem);
if ($info === false) {
    exit("Not a certificate: " . openssl_error_string() . PHP_EOL);
}

echo $info['subject']['CN'], PHP_EOL;
echo $info['issuer']['O'] ?? '', PHP_EOL;
echo $info['extensions']['subjectAltName'] ?? '', PHP_EOL;
echo date('c', $info['validTo_time_t']), PHP_EOL;
echo $info['serialNumberHex'], PHP_EOL;

$days = intdiv($info['validTo_time_t'] - time(), 86400);
echo "$days days left", PHP_EOL;

echo openssl_x509_fingerprint($pem, 'sha256'), PHP_EOL;

openssl_x509_parse() returns the extensions as openssl's own display strings, which is convenient to print and awkward to parse further.

OpenSSL (shell)

# Everything, the long way
openssl x509 -in cert.pem -noout -text

# Just the fields you usually want
openssl x509 -in cert.pem -noout -subject -issuer -enddate -ext subjectAltName

# Fingerprint (DER bytes hashed, same as the tool)
openssl x509 -in cert.pem -noout -fingerprint -sha256

# DER to PEM
openssl x509 -inform der -in cert.der -out cert.pem

# The chain a live server actually sends
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

Common errors and how to fix them

unable to load certificate / Expecting: TRUSTED CERTIFICATE
The file is DER, not PEM, or the BEGIN and END lines were damaged when copying. Add -inform der, or upload the file here, which detects the format from the first byte.
The browser says NET::ERR_CERT_COMMON_NAME_INVALID but the CN is right
Browsers ignore the CN and check only the Subject Alternative Name list. Reissue the certificate with the hostname in the SANs, including www. if you serve both.
Chain incomplete or unable to get local issuer certificate
The server sends only the leaf. Configure it to send the leaf followed by the intermediates (usually a fullchain.pem file). Paste the s_client output here to see which certificates the server sends and in what order.
The pasted text is a CERTIFICATE REQUEST or a PRIVATE KEY
A CSR is the request you send to a CA, not the certificate you get back; read it with openssl req -text. A private key should never be pasted into any web page, and the tool will not display it.
Element claims N bytes but only M remain
The Base64 is truncated, usually a line lost while copying from a terminal or an email. Copy the block again, including the END line.

Good to know

Certificates are DER-encoded ASN.1 (X.690), and this page parses them with a small hand-written reader rather than a library. It covers the fields RFC 5280 defines for TLS certificates plus the common CA/Browser Forum policy OIDs, Certificate Transparency SCTs and OCSP Must-Staple. Unknown extensions are shown by OID with their raw bytes, so nothing is silently dropped.

Specifications and references

This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.

Frequently Asked Questions

How do I check when an SSL certificate expires?

Paste the PEM and read the Not after line, or the badge on the card, which counts the days left. From a terminal, openssl x509 -in cert.pem -noout -enddate prints the same date.

Can I paste a whole certificate chain?

Yes. Every BEGIN CERTIFICATE block becomes its own card, in the order pasted, and each card says whether its issuer matches the subject of the next one. Text outside the blocks, such as openssl s_client output, is ignored.

Does it verify the certificate?

No. It decodes the fields but does not check the signature, query OCSP or CRLs, or compare against a trust store, so a certificate that decodes cleanly can still be rejected by a browser.

What is the difference between PEM, CRT, CER and DER?

DER is the binary encoding. PEM is the same bytes in Base64 between BEGIN and END lines. .crt and .cer are only file extensions and can hold either, which is why the upload accepts both and detects the format from the content.

Is it safe to paste my certificate here?

A certificate is public: every server sends it to every visitor. Parsing happens in your browser and nothing is uploaded. A private key is a different matter, and the tool refuses to display one if you paste it by mistake.

Related

For tokens rather than certificates, use the JWT decoder. The fingerprints here are SHA-256 and SHA-1 digests of the DER bytes; the SHA generator computes the same algorithms over text. For raw Base64 that is not a certificate, use the Base64 encoder.

More Security & Hashing Tools

Browse all security & hashing tools

Copied to clipboard!