Certificate Signing Request Decoder

Paste a CSR and see exactly what you’re sending to a certificate authority — subject, public key, requested domains, signature algorithm and the problems that will bite you later.

A Certificate Signing Request (CSR) is the PKCS#10 document you hand to a CA when ordering an SSL/TLS certificate: your identity (the subject DN), the public key to be certified, and — usually — the domains you want covered in a Subject Alternative Name extension. This decoder parses the full ASN.1/DER structure in your browser and shows every field in plain English: subject, public key details (RSA modulus and exponent, EC curve, Ed25519), requested domains (DNS names, IPs, emails from the SAN extension), the signature algorithm, plus a findings panel that flags the mistakes that actually break deployments — missing SANs, weak RSA keys, deprecated signature algorithms.

🔒 100% private — nothing is uploaded or stored. The CSR is parsed entirely in your browser with a built-in ASN.1/DER parser written in plain JavaScript — no libraries, no network requests, no server round-trip. Your CSR (and the private key it was signed with, which is never in the file) never leaves this page. Nothing is logged or stored on our side.

Decode a CSR

Paste the output of openssl req -new, or the CSR file from your server, control panel or load balancer (nginx, HAProxy, Apache). Raw Base64 without the -----BEGIN CERTIFICATE REQUEST----- headers works too.

What is a CSR, and what’s inside it?

A Certificate Signing Request is a PKCS#10 document (RFC 2986) that binds three things together: who you are (the subject Distinguished Name), which public key should be certified, and a signature made with the matching private key. That last part is the proof of possession — when the CA verifies it, they know the entity submitting the CSR actually holds the private key, so they can safely certify the public half.

The DER structure looks like this:

CertificationRequest ::= SEQUENCE {{ certificationRequestInfo: SEQUENCE {{ version INTEGER (always 0), subject Name, -- your DN fields (C, O, CN, ...) subjectPublicKeyInfo, -- key algorithm + public key attributes [0] -- usually the requested extensions (SAN!) }}, signatureAlgorithm AlgorithmIdentifier, -- how the CSR itself is signed signature BIT STRING -- private-key signature over the info }}

The private key is never in the CSR — only its public half. That’s why it’s safe to paste a CSR into this page, or email it to a CA, or open it in any tool: the file alone can never unlock anything.

The attributes field is where SANs live

The attributes [0] field carries extensionRequest (OID 1.2.840.113549.1.9.14): a nested DER blob of the X.509 extensions you want in the final certificate — most importantly subjectAltName (OID 2.5.29.17), which lists every DNS name, IP address and email the certificate should cover. If you generate a CSR without it, the CA issues a certificate with no SANs and modern browsers will refuse to trust it for any hostname.

How to generate a CSR (OpenSSL)

One-liner (OpenSSL 1.1.1+), with SANs:

openssl req -new -newkey rsa:2048 -nodes \ -keyout server.key \ -out server.csr \ -subj "/C=AU/O=Your Company/CN=www.example.com" \ -addext "subjectAltName=DNS:www.example.com,DNS:example.com"

Multiple SANs, or older OpenSSL — use a config file:

# csr.cnf [req] distinguished_name = dn req_extensions = v3_req prompt = no [dn] C = AU O = Your Company CN = www.example.com [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = www.example.com DNS.2 = example.com DNS.3 = api.example.com IP.1 = 203.0.113.10

Then openssl req -new -key server.key -out server.csr -config csr.cnf. Keep server.key safe — the private key stays on your machine for the whole process and is what you’ll install next to the issued certificate.

Verify it before sending:

openssl req -in server.csr -noout -verify -text

Why Subject Alternative Names matter

Historically, browsers matched the hostname against the certificate’s Common Name. That was ambiguous (which of several names wins?), so every major browser vendor agreed to deprecate it: since Chrome 58 / Firefox 60 / Safari 9.1 (2015–2017), the CN is ignored for hostname verification and only SAN entries count. The practical consequences:

  • One domain, one SAN entry. A certificate for example.com and www.example.com needs both listed — the CN doesn’t cover either on its own.
  • Wildcards are SAN entries too: *.example.com covers one label level only (api.example.com, not a.b.example.com).
  • IP addresses need IP SANs (e.g. internal load balancers) — a DNS name will never validate an IP.
  • Email certificates (for S/MIME) use email: entries in the same extension.

The findings panel above flags a missing SAN, a CN that doesn’t match any SAN entry, and SANs with typos you can spot at a glance.

Key algorithm recommendations

RSA 2048–4096The safe default everywhere. 2048-bit is the current minimum; 3072 or 4096 gives more headroom at a small handshake cost. Below 2048 is a hard no.
ECC P-256The modern favourite for TLS: ~128-bit security, smaller keys and certificates, faster handshakes on mobile. Equivalent strength to RSA 3072.
ECC P-384~192-bit security for long-lived or high-value certificates (equivalent to RSA 7680).
Ed25519Fully supported by current browsers and clients; very fast signatures. A great choice where you control both ends.
DSADeprecated (RFC 8418) — do not use for new certificates.

The signature algorithm on the CSR itself (e.g. SHA-256 with RSA, ECDSA with SHA-256, EdDSA) just protects the CSR in transit to the CA — it does not determine the certificate’s strength, but SHA-1-signed CSRs are a sign of old tooling worth updating.


Luke Keam
Thank you for reading. Get in touch
Luke Keam | techgeek.biz