A CSR (Certificate Signing Request) is a block of encoded text you generate on your web server and submit to a Certificate Authority (CA) to get an SSL/TLS certificate. It contains your public key and identity information — your domain name, organization name, and location. The CA uses this information to issue a certificate that proves your server's identity to browsers.
Step 1: Generate a Private Key and CSR
Use OpenSSL to generate both in a single command. This is the standard approach for all major web servers:
# Generate RSA 2048-bit key + CSR interactively:
openssl req -new -newkey rsa:2048 -nodes \
-keyout yourdomain.key \
-out yourdomain.csr
# You'll be prompted for each field:
# Country Name (2 letter code) [AU]: US
# State or Province Name (full name): California
# Locality Name (eg, city): San Francisco
# Organization Name (eg, company): Acme Corp Ltd
# Organizational Unit Name: [leave blank — deprecated]
# Common Name (e.g. server FQDN): yourdomain.com
# Email Address: [optional — you can leave blank]
# A challenge password: [leave blank for modern CAs]
# Or generate non-interactively with -subj flag (good for automation):
openssl req -new -newkey rsa:2048 -nodes \
-keyout yourdomain.key \
-out yourdomain.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Acme Corp Ltd/CN=yourdomain.com"
# For ECC (smaller key, same security as 3072-bit RSA):
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
-keyout yourdomain-ecc.key \
-out yourdomain-ecc.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Acme Corp Ltd/CN=yourdomain.com"
Step 2: Add Subject Alternative Names (SANs)
Since 2017, Chrome requires SANs — the Common Name alone is no longer honored. Always include at least DNS:yourdomain.com and DNS:www.yourdomain.com:
# Create a config file — san.cnf:
cat > san.cnf <<EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
C=US
ST=California
L=San Francisco
O=Acme Corp Ltd
CN=yourdomain.com
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = yourdomain.com
DNS.2 = www.yourdomain.com
DNS.3 = mail.yourdomain.com
EOF
# Generate CSR using the config file:
openssl req -new -newkey rsa:2048 -nodes \
-keyout yourdomain.key \
-out yourdomain.csr \
-config san.cnf
Step 3: Verify the CSR Before Submitting
Always decode and verify the CSR contents before submitting to the CA. A mistake here means the issued certificate will be wrong and you'll need to reissue:
# Decode and display all CSR contents:
openssl req -in yourdomain.csr -noout -text
# Check only the subject (most important):
openssl req -in yourdomain.csr -noout -subject
# subject=C=US, ST=California, L=San Francisco, O=Acme Corp Ltd, CN=yourdomain.com
# Verify the public key:
openssl req -in yourdomain.csr -noout -pubkey
# Verify the CSR signature is valid (self-consistency check):
openssl req -in yourdomain.csr -noout -verify
# verify OK ← CSR is not corrupted
What the CSR text output looks like:
$ openssl req -in yourdomain.csr -noout -text
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C=US, ST=California, L=San Francisco, O=Acme Corp Ltd, CN=yourdomain.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Attributes:
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:yourdomain.com, DNS:www.yourdomain.com
Signature Algorithm: sha256WithRSAEncryption
verify OK
Step 4: Submit to a Certificate Authority
Open yourdomain.csr in a text editor — it looks like this:
-----BEGIN CERTIFICATE REQUEST-----
MIICozCCAYsCAQAwXjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx
FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xFDASBgNVBAoMC0FjbWUgQ29ycCBMdGQx
DDAKBgNVBAMMBGFjbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw...
-----END CERTIFICATE REQUEST-----
Copy the entire block (including the -----BEGIN and -----END lines) and paste it into your CA's order form. For Let's Encrypt, this is automated by Certbot — you don't need to manually submit a CSR unless you use certbot certonly --csr.
Common CSR Mistakes to Avoid
- Typo in Common Name — certificate is issued for the wrong domain, immediate re-issue required
- Forgetting SANs — Chrome 58+ ignores CN; the certificate will cause errors without a SAN field
- Sharing the private key — the
.key file must stay on your server only, never emailed or uploaded to a CA
- Generating a new key without updating the certificate — the key and certificate are a matched pair; a new key requires a new CSR and re-issuance
- Using MD5 or SHA-1 — always use SHA-256 (
-sha256 is the default in OpenSSL 1.0.2+)
Generate a CSR Without OpenSSL
If you don't have command-line access, you can use our free online CSR generator:
Generate a CSR on Windows
Windows Server
PowerShell / certreq
Windows has two built-in ways to generate a CSR: the certreq command-line tool (works on all Windows versions) and the IIS Manager GUI (for IIS users). Both produce a PKCS#10 CSR compatible with any CA.
Method 1: certreq (All Windows Versions)
Create an INF file that defines the certificate parameters. Save it as C:\ssl\csr.inf:
[Version]
Signature="$Windows NT$"
[NewRequest]
Subject = "CN=yourdomain.com, O=Your Company Ltd, L=City, S=State, C=US"
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = False
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
HashAlgorithm = SHA256
[EnhancedKeyUsageExtension]
OID = 1.3.6.1.5.5.7.3.1 ; Server Authentication
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=yourdomain.com&"
_continue_ = "dns=www.yourdomain.com&"
Generate the CSR and private key:
:: Create C:\ssl directory first
mkdir C:\ssl
:: Generate the CSR — private key is stored in Windows Certificate Store
certreq -new C:\ssl\csr.inf C:\ssl\yourdomain.csr
:: View the generated CSR
type C:\ssl\yourdomain.csr
The private key is stored in the Windows Certificate Store (not as a file). When your CA issues the certificate, use certreq -accept certificate.crt to install it and link it to the private key automatically.
Method 2: OpenSSL on Windows
If you prefer OpenSSL (more portable, exportable key files), install it via winget:
:: Install OpenSSL
winget install ShiningLight.OpenSSL
:: Generate private key and CSR (identical to Linux OpenSSL commands)
openssl genrsa -out yourdomain.key 2048
openssl req -new -key yourdomain.key -out yourdomain.csr ^
-subj "/C=US/ST=State/L=City/O=Your Company/CN=yourdomain.com"
:: Multi-domain (SAN) CSR — create san.cnf first, then:
openssl req -new -key yourdomain.key -out yourdomain.csr -config san.cnf
Method 3: IIS Manager GUI
Open IIS Manager → select the server node → Server Certificates → Create Certificate Request in the right panel. Fill in the distinguished name fields, choose RSA 2048-bit or 4096-bit, and save the CSR file to disk. Submit this file to your CA.
Generate a CSR on macOS
macOS
Terminal / Keychain
Method 1: OpenSSL in Terminal (Recommended)
macOS includes LibreSSL (compatible with OpenSSL commands). For the latest OpenSSL, install via Homebrew: brew install openssl.
# Generate private key and CSR — identical syntax to Linux
openssl genrsa -out yourdomain.key 2048
openssl req -new -key yourdomain.key -out yourdomain.csr \
-subj "/C=US/ST=State/L=City/O=Your Company/CN=yourdomain.com"
# Verify the CSR content
openssl req -text -noout -in yourdomain.csr
Method 2: Keychain Access GUI
Open Keychain Access → from the menu bar: Keychain Access → Certificate Assistant → Request a Certificate From a Certificate Authority. Fill in your email, common name (domain), and choose "Saved to disk." This generates a .certSigningRequest file — rename it to .csr for your CA.
The Keychain method uses macOS's built-in key generation — the private key is stored in your login keychain (not as a file). If you need to install the certificate on a server later, the OpenSSL method gives you both files directly.