A Certificate Signing Request (CSR) is a block of encoded data that you send to a Certificate Authority when requesting a TLS certificate. It contains your public key and the identity information you want in the certificate (domain name, organization, location). The CA verifies your identity, signs your public key, and returns the certificate.
Think of it as a job application: you provide your details (CSR), the employer verifies them (CA validation), and issues you an ID badge (certificate). The private key stays with you — it’s never in the CSR.
What’s Inside a CSR
A PKCS#10 CSR contains:
Certificate Request:
Data:
Version: 1 (0x0)
Subject: CN=api.example.com, O=My Company, L=New York, ST=NY, C=US
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey (P-256)
Public-Key: (256 bit)
Attributes:
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:api.example.com, DNS:api-v2.example.com
Signature Algorithm: ecdsa-with-SHA256
Signature: (proves you hold the private key)
Key fields:
- Subject — who you are (CN, O, OU, L, ST, C)
- Public Key — the key that will be in the certificate
- SANs — all domain names the certificate should cover
- Signature — proves you possess the matching private key (proof of possession)
Generating a CSR with OpenSSL
ECDSA P-256 (Recommended)
# Step 1: Generate private key
openssl ecparam -genkey -name prime256v1 -out server.key
# Step 2: Generate CSR
openssl req -new -key server.key -out server.csr \
-subj "/CN=api.example.com/O=My Company/L=New York/ST=NY/C=US" \
-addext "subjectAltName=DNS:api.example.com,DNS:api-v2.example.com,DNS:www.example.com"
# Step 3: Verify CSR contents
openssl req -in server.csr -noout -text
RSA 2048 (Legacy Compatibility)
# Generate key + CSR in one command
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr \
-subj "/CN=api.example.com/O=My Company/C=US" \
-addext "subjectAltName=DNS:api.example.com,DNS:www.example.com"
Using a Config File (Complex SANs)
# csr.conf
[req]
default_bits = 2048
prompt = no
distinguished_name = dn
req_extensions = v3_req
[dn]
CN = api.example.com
O = My Company
L = New York
ST = NY
C = US
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = api.example.com
DNS.2 = api-v2.example.com
DNS.3 = *.internal.example.com
IP.1 = 10.0.1.50
openssl req -new -key server.key -out server.csr -config csr.conf
Common CSR Mistakes
1. Missing SANs (Subject Alternative Names)
Problem: CSR has only CN (Common Name) but no SAN extension. Modern browsers require SANs — they ignore the CN entirely.
# WRONG — no SANs
openssl req -new -key server.key -out server.csr -subj "/CN=example.com"
# Certificate will show "hostname mismatch" in modern clients!
# RIGHT — include SANs
openssl req -new -key server.key -out server.csr \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com"
2. Wrong Key in CSR
Problem: CSR was generated with one key, but you deploy a different key with the certificate. The key/cert pair won’t match.
# Verify key matches CSR
openssl req -noout -modulus -in server.csr | md5sum
openssl rsa -noout -modulus -in server.key | md5sum
# Both MD5 hashes must match
3. Typo in Domain Name
Problem: CSR says api.exmaple.com (typo). CA issues certificate for the typo. You deploy it on api.example.com. Hostname mismatch.
Fix: Always verify CSR contents before submitting:
openssl req -in server.csr -noout -text | grep -A2 "Subject Alternative Name"
4. Weak Key Algorithm
Problem: CSR uses RSA-1024 or DSA. CA rejects it (minimum RSA-2048 per CA/Browser Forum Baseline Requirements).
Fix: Use ECDSA P-256 (recommended) or RSA-2048 minimum.
5. Including the Private Key
Problem: Someone accidentally sends the private key file to the CA instead of (or alongside) the CSR. The private key is now compromised.
Fix: The CSR file ends with -----END CERTIFICATE REQUEST-----. The private key ends with -----END PRIVATE KEY-----. Never send anything ending in “PRIVATE KEY” to anyone.
CSR in Automated Workflows
ACME (Let’s Encrypt) — CSR Generated Automatically
# Certbot generates key + CSR internally — you never see the CSR
certbot certonly --nginx -d example.com -d www.example.com
# Key: /etc/letsencrypt/live/example.com/privkey.pem
# Cert: /etc/letsencrypt/live/example.com/fullchain.pem
cert-manager (Kubernetes) — CSR Generated Automatically
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-tls
spec:
secretName: api-tls-secret
issuerRef:
name: letsencrypt-prod
dnsNames:
- api.example.com
privateKey:
algorithm: ECDSA
size: 256
# cert-manager generates key + CSR, submits to CA, stores result in Secret
Manual Submission (Enterprise CAs)
# Generate CSR
openssl req -new -key server.key -out server.csr -config csr.conf
# Submit to CA portal (DigiCert, Sectigo, internal CA)
# Paste CSR content (including BEGIN/END markers) into the CA's web form
# Or submit via API
curl -X POST https://ca.example.com/api/v1/certificates \
-H "Authorization: Bearer $TOKEN" \
-d "{\"csr\": \"$(cat server.csr | base64)\"}"
CSR vs Certificate: What’s the Difference?
| CSR | Certificate | |
|---|---|---|
| Contains | Public key + requested identity | Public key + verified identity + CA signature |
| Signed by | Your private key (proof of possession) | CA’s private key (trust delegation) |
| Purpose | Request a certificate | Prove identity to clients |
| Lifetime | Used once (for issuance) | Valid for days-years |
| Who has it | You send to CA | CA returns to you, you deploy on server |
FAQ
Q: Do I need a new CSR for every certificate renewal? A: Best practice: yes (generate a new key pair + new CSR at each renewal). This provides automatic key rotation. ACME clients and cert-manager do this by default.
Q: Can I reuse a CSR? A: Technically yes (same public key, same identity). But reusing means you’re not rotating the key — which defeats one of the security benefits of renewal.
Q: Does the CSR determine the certificate validity period? A: No. The CA determines validity based on their policy and your request. The CSR doesn’t contain a validity field.
Q: What format should the CSR be in?
A: PEM format (base64-encoded, wrapped in -----BEGIN CERTIFICATE REQUEST----- markers). This is what OpenSSL generates by default and what CAs expect.
Q: Can I generate a CSR without OpenSSL?
A: Yes — use our free CSR Generator tool for a browser-based option. Or use keytool (Java), certreq (Windows), or programming language libraries.