How to Generate a Proper Certificate Signing Request

How to Generate a Proper Certificate Signing Request

A certificate signing request is the file every SSL/TLS certificate starts from, and getting it wrong is one of the most common reasons a certificate installation fails days after issuance – wrong common name, missing SAN entries, or a private key that doesn’t match the CSR anymore. This guide walks through generating a CSR correctly, the fields that actually matter, and the mistakes that cause CA rejections or mismatched-certificate errors on go-live day.

What a CSR Actually Contains

A CSR is a PKCS#10-formatted block of Base64 text that bundles your public key, your domain and organization details, and a signature proving you hold the matching private key. It does not contain the private key itself – that’s a myth worth killing early. Plenty of admins assume a CSR is sensitive because it “has key stuff in it,” and either refuse to paste it into a CA’s web form or store it with the same paranoia as the private key. The CSR is safe to email, paste, or upload; the private key generated alongside it is the part that needs protecting, ideally following the storage guidance in private key protection best practices.

Generating a CSR with OpenSSL

On Linux, macOS, or any box with OpenSSL 1.1.1 or 3.x installed, the standard one-liner generates both a new 2048-bit RSA key and the CSR in one step:

openssl req -new -newkey rsa:2048 -nodes -keyout example.com.key -out example.com.csr

You’ll be prompted for Country (C), State (ST), Locality (L), Organization (O), Organizational Unit (OU), and Common Name (CN). CN should be the exact hostname the certificate will protect – www.example.com, not example.com, if that’s what users actually type. Since the CA/Browser Forum deprecated CN-only matching in September 2020 (Chrome and Firefox both enforce this), the Subject Alternative Name field is what browsers actually check, so it needs to be set explicitly with a config file:

openssl req -new -newkey rsa:2048 -nodes -keyout example.com.key -out example.com.csr -config san.cnf

where san.cnf includes a [alt_names] section listing DNS.1 = example.com, DNS.2 = www.example.com, and so on. Skipping this step is the single most common reason a freshly issued certificate throws NET::ERR_CERT_COMMON_NAME_INVALID the moment it’s deployed.

Choosing Key Type and Size

RSA 2048-bit remains the safe default accepted by every CA and every client back to Windows XP SP3-era systems, though anything below that – RSA 1024 in particular – has been rejected by public CAs since roughly 2013 and will bounce your request outright. ECC (prime256v1, sometimes called P-256) produces a much smaller key with equivalent security to RSA 3072, and cuts handshake CPU cost noticeably on high-traffic edge nodes. For a deeper comparison of tradeoffs, see how ECC certificates compare to RSA in modern setups. Generating an ECC CSR swaps the key parameters:

openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -keyout example.com.key -out example.com.csr

Server-Specific Generation Paths

Not every environment uses OpenSSL directly. IIS admins typically generate the CSR through the Server Certificates snap-in in IIS Manager, which stores the pending request internally and expects the completed certificate to be re-imported against that same pending request – lose that pending request and you’ll need to start over with a fresh CSR and key pair. nginx and Apache deployments almost always go through OpenSSL or certbot’s manual mode. Cloud-managed certificates (AWS ACM, GCP Certificate Manager, Azure Key Vault) skip CSR generation entirely for their own issued certs, though they still accept externally generated CSRs if you’re importing a certificate from a third-party CA.

Verifying the CSR Before Submission

An experienced practitioner never submits a CSR to a CA without checking it first – a rejected or misissued certificate costs a business day of back-and-forth with support. Two commands catch nearly everything:

openssl req -text -noout -verify -in example.com.csr

This decodes the CSR and confirms the signature is valid, and prints every field including the SAN list, so a quick scan confirms CN and SAN entries match what’s intended. Second, confirm the CSR’s public key matches the private key it was generated with:

openssl req -noout -modulus -in example.com.csr | openssl md5
openssl rsa -noout -modulus -in example.com.key | openssl md5

If those two hashes don’t match, something got mixed up between key generation and CSR creation – usually because a CSR got regenerated against an old key file left over from a previous renewal.

Common Mistakes That Cause Rejections or Outages

Reusing the same private key across multiple renewal cycles is the most frequent shortcut teams take, usually to avoid re-pinning the key in a load balancer or mobile app that uses certificate pinning – but it defeats the point of periodic rotation and means a single key compromise affects years of certificate history. Generating the CSR on one machine and the actual key on another – common when a CSR gets forwarded between a sysadmin and a security team – breaks the key-CSR match entirely. And leaving the Organization field blank or inconsistent across CSRs causes friction specifically for OV and EV certificates, where CAs cross-check business registry data against exactly what’s submitted; the validation-level differences are covered in DV, OV, and EV certificates explained.

Frequently Asked Questions

Can a CSR be reused for a certificate renewal?
Technically yes, as long as the domain and SAN list haven’t changed, but it means renewing without rotating the private key. Most security teams recommend generating a fresh key and CSR at every renewal cycle rather than reusing one indefinitely.

What happens if the private key is lost after submitting a CSR?
The CSR itself becomes useless – once the matching private key is gone, any certificate issued against that CSR can’t be installed anywhere. A new key pair and CSR have to be generated and resubmitted to the CA.

Does a CSR expire?
No, a CSR itself doesn’t have an expiration date. It’s just a signed request; once a CA issues a certificate from it, the CSR has served its purpose and the issued certificate’s validity period is what matters going forward.

Once the certificate comes back from the CA, the next real checkpoint is confirming it actually installed correctly across every server and load balancer node – worth running through how to verify SSL certificate installation is correct before calling the job done. A CSR generated carelessly rarely fails at generation time; it fails three days later when someone notices the SAN list was wrong all along.