SSL CSR Generator

Generate a PKCS#10 certificate signing request and its matching private key in your browser. RSA 2048/4096 or ECDSA P-256, SHA-256, with SAN.

🌐 Español

🔒 Private by design: your text is processed locally in your browser and never uploaded to any server.

The field names the parser accepts, and the aliases it forgives

There is one text box on this page, so the certificate details arrive as lines of field: value text rather than as a form. The parser is more forgiving than that sounds. It lowercases each key and throws away everything that is not a letter before matching, which means CN, commonName, common_name and Common Name all resolve to the same field.

The aliases go further than the canonical names. domain, hostname and domainname are all treated as the common name. company maps to organization, department to organizational unit, city to locality, province to state, and countryCode to country. For extra hostnames you can write san, sans, altnames, subjectAltName or additionalDomains, and repeat the line as many times as you like instead of packing everything onto one comma-separated line.

Only the first colon on a line splits key from value, so a value containing a colon survives intact. Blank lines and lines starting with # are ignored outright.

Two values get real validation. Country must be exactly two letters, and it is uppercased and encoded as an ASN.1 PrintableString while every other subject attribute is encoded as a UTF8String. The common name and every SAN entry go through a deliberately permissive hostname check: no whitespace, nothing outside letters, digits, dots, hyphens and asterisks, no leading or trailing dot or hyphen, no doubled dots, and a leading asterisk only when it is followed by a dot. That looseness is on purpose, so internal names like localhost or printer1 are not rejected.

Requesting a certificate for a domain and two subdomains

  1. Paste your details into the box, one field per line. The only line that is genuinely required is the common name.
  2. Add organization, organizationalUnit, locality, state and country as far as your Certificate Authority asks for them.
  3. Add the extra hostnames on a san line, comma separated. Your common name is prepended to that list automatically and duplicates are removed case-insensitively, so repeating it changes nothing.
  4. Choose a Key type. The three entries read RSA 2048-bit (widely compatible, good default), RSA 4096-bit (stronger, slower to generate), and ECDSA P-256 (modern, fast, smaller keys).
  5. Click the action button, which is labeled SSL CSR Generator and switches to a working state while the key pair is produced.
  6. The input box and the dropdown are replaced by the result. Use Copy to clipboard to take everything, or select just the block you need, then Process another when you are done.

Two PEM blocks in one box, and which one the CA gets

The result is a single labeled text block with three sections. The first holds the certificate signing request, wrapped in a standard CERTIFICATE REQUEST PEM header. The second holds the private key, exported in PKCS#8 and wrapped in a PRIVATE KEY header. The third is a NOTES section listing the key type you picked, the finished subject in comma-separated form, the final SAN list, and any field names the parser did not recognize.

Copying copies both blocks, which is the one trap here. A CA form that asks for a CSR wants the first block and nothing else, so highlight it by hand rather than pasting the whole box. The private key is yours to keep. A Certificate Authority never needs it and should never be sent it.

There is no download button on this shell and no storage of any kind, so the copy in that box is the only copy of the key that has ever existed. Save it to a file before you leave the page. Once you have, SSL Certificate Decoder will read a .csr file back and print its subject, SAN list and signature check, which is a useful sanity pass before you hand it over.

RSA 2048, RSA 4096 and P-256, and what actually changes

RSA 2048 is the default because it is the option nothing anywhere refuses. RSA 4096 is the same algorithm at double the modulus, and the label says the quiet part out loud: it is slower to generate. That work happens through Web Crypto inside your own tab, so the wait is your device’s, not a queue’s. ECDSA P-256 produces a much smaller key and a smaller resulting certificate, and every current CA and browser accepts it.

What does not change is the digest. All three paths sign with SHA-256. There is also no RSA 3072, no P-384 and no Ed25519 here: the key type resolver accepts exactly three values and quietly falls back to RSA 2048 for anything else.

The subject-encoding bug openssl caught before this shipped

Worth telling, because it is the reason this tool builds its own ASN.1 instead of trusting a convenience API. The obvious approach is to push every subject attribute onto the library’s flat attribute array and let it generate the schema. Do that and all six attributes end up bundled into a single multi-valued relative distinguished name, which openssl req -text prints joined with plus signs rather than as the conventional comma-separated form.

The fix was to hand-build the correct shape directly: a SEQUENCE of separate single-attribute SETs, ordered country, state, locality, organization, organizational unit, common name, then hand the library those raw DER bytes. Every key type was re-checked afterwards with openssl req -verify -text. On top of that, the code verifies its own signature before returning anything, and refuses to hand back a request that fails that check.

Limits worth knowing before you rely on this

The private key is unencrypted. There is no passphrase option, deliberately, because shipping an unverified encryption layer for something this sensitive is worse than not shipping one. Run openssl pkey -in key.pem -aes256 -out key-encrypted.pem over the saved file if you need one, since that handles the PKCS#8 block this page emits for all three key types.

The only extension written is subjectAltName, carried in a PKCS#9 extensionRequest attribute. No key usage, no extended key usage, no basic constraints. Nothing is submitted anywhere either: proving you control the domain and collecting the signed certificate are separate steps with your CA or an ACME client.

For server access rather than a website certificate, SSH Key Generator is the right page instead. Once the certificate comes back, Nginx and .htaccess Config Generator will write the HTTPS server block, and the rest of the collection sits on the developer tools hub.

See it in action

Screenshot of the SSL CSR Generator tool with the sample input “cn: sysfenix.com country: ES state: Madrid local…”, Key type set to RSA 2048-bit (widely compatible, good default)
SSL CSR Generator mid-process: the sample input “cn: sysfenix.com country: ES state: Madrid local…”, Key type set to RSA 2048-bit (widely compatible, good default).
Screenshot of the SSL CSR Generator result screen showing the generated output “=== CERTIFICATE SIGNING REQUEST (CSR) — submit O…”
The finished result: the generated output “=== CERTIFICATE SIGNING REQUEST (CSR) — submit O…”. The download link is a local blob URL — the file never leaves your device.

Frequently asked questions

Which signature algorithm ends up inside the request?

SHA-256, for all three key choices. An RSA key is generated as RSASSA-PKCS1-v1_5 with a public exponent of 65537 and hashed with SHA-256, and the P-256 key signs with ECDSA over SHA-256. The dropdown therefore changes the key algorithm and its size, never the digest.

Is the private key shown on screen, and can I recover it after I leave?

It is shown, in full, in the same read-only box as the request itself, wrapped in a PKCS#8 PEM block. It is never recoverable afterwards. Nothing is written to browser storage, so refreshing the page, closing the tab or clicking Process another destroys the only copy that ever existed. Copy it out before you navigate away.

Can I put an IP address or an email address in the SAN list?

Not as a proper iPAddress entry. Every SAN entry is written as a dNSName, so an email address or a URI is rejected outright by the shape check. An IP literal such as 192.168.1.10 slips through that check and is written as a DNS name, which is not what a CA expects, so keep the list to hostnames. The check is deliberately loose about what counts as one, which is why bare internal names like localhost or printer1 and wildcards written as an asterisk followed by a dot are all accepted.

What happens to a line whose field name I misspell?

Nothing fatal. Unrecognized field names are collected rather than treated as errors, and they are echoed back to you by name in the NOTES section under the two PEM blocks so you can spot the typo. A line with no colon on it at all is skipped in silence, as are blank lines and any line starting with a hash.

Why did a bad input give me a vague failure message instead of the real reason?

Because this page rides the site's shared paste-in component, which catches every exception and replaces it with one generic sentence, sending the specific message to the browser console instead. The underlying module does raise precise errors for a missing common name, a country code that is not exactly two letters, or a hostname containing a space. Open the developer console if you need to read the real one.

Does the page download a crypto library before I press the button?

No. The two PKCS#10 libraries this tool leans on are pulled in by dynamic import inside the functions that need them, so a visitor who reads the article and leaves never fetches either one. Key generation itself uses the browser's built-in Web Crypto implementation, which needs no download at all.

Related tools