OpenSSL Cheatsheet
CSRs and Certificates
Use this OpenSSL reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Create a CSR from an existing key
A certificate signing request bundles a public key plus the subject and the extensions you want, signed by the matching private key.
openssl req -new -key key.pem -out req.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Acme Inc/CN=example.com"-subj skips the interactive prompts. Without it OpenSSL asks for every field
and a bare Enter leaves it empty, which some CAs reject.
Key and CSR in one command
openssl req -new -newkey rsa:2048 -noenc \ -keyout key.pem -out req.csr \ -subj "/C=US/O=Acme Inc/CN=example.com" # EC instead of RSA openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \ -noenc -keyout ec.key -out req.csr -subj "/CN=example.com"
-noenc (formerly -nodes) writes the key unencrypted, which is what a web
server needs to start without a prompt.
Subject Alternative Names
Every modern browser ignores CN and reads SAN only. A CSR without a SAN produces a certificate no browser will trust, so always add one.
openssl req -new -key key.pem -out req.csr \ -subj "/CN=example.com" \ -addext "subjectAltName=DNS:example.com,DNS:www.example.com" # Wildcard plus apex openssl req -new -key key.pem -out req.csr \ -subj "/CN=example.com" \ -addext "subjectAltName=DNS:example.com,DNS:*.example.com" # IPs and emails in the same list openssl req -new -key key.pem -out req.csr \ -subj "/CN=box.internal" \ -addext "subjectAltName=DNS:box.internal,IP:10.0.0.5,IP:127.0.0.1"
-addext may be repeated, once per extension:
openssl req -new -key key.pem -out req.csr -subj "/CN=example.com" \ -addext "subjectAltName=DNS:example.com" \ -addext "keyUsage=critical,digitalSignature,keyEncipherment" \ -addext "extendedKeyUsage=serverAuth,clientAuth"
Subject field reference
The -subj string is slash separated, /Key=Value, and order is conventional
rather than enforced.
| Key | Name | Example | Notes |
|---|---|---|---|
C | Country | US | Two letters, uppercase, ISO 3166 |
ST | State or province | California | Spell it out |
L | Locality | San Francisco | City |
O | Organization | Acme Inc | Legal name for OV/EV |
OU | Organizational unit | IT | Ignored by public CAs now |
CN | Common name | example.com | Cosmetic for TLS, SAN wins |
emailAddress | ops@acme.com | Used by S/MIME, not TLS |
A value containing a slash needs escaping, or switch to a config file:
openssl req -new -key key.pem -out req.csr \
-subj "/O=Acme\/Widgets/CN=example.com"Read a CSR back
Never send a CSR you have not read. This is the single most common source of a rejected order.
openssl req -in req.csr -noout -text # everything openssl req -in req.csr -noout -subject # subject line only openssl req -in req.csr -noout -verify # self-signature check openssl req -in req.csr -noout -pubkey # embedded public key
Pull just the SANs out:
openssl req -in req.csr -noout -text | grep -A1 "Subject Alternative Name"
Confirm the CSR matches the key you think it does:
openssl req -in req.csr -noout -pubkey | openssl sha256 openssl pkey -in key.pem -pubout | openssl sha256
Same digest means same key pair.
Config file instead of flags
For anything repeated, put the extensions in a file. This is the only way to
get a SAN into x509 -req on OpenSSL 1.1.x.
# csr.cnf [req] default_md = sha256 prompt = no distinguished_name = dn req_extensions = v3_req [dn] C = US O = Acme Inc CN = example.com [v3_req] basicConstraints = CA:FALSE keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt [alt] DNS.1 = example.com DNS.2 = www.example.com IP.1 = 10.0.0.5
openssl req -new -key key.pem -config csr.cnf -out req.csr
Gotchas
- -addext needs OpenSSL 1.1.1 or newer. On older builds use -config
with a req_extensions section.
- -addext silently loses to -config when the same extension appears in
both. Pick one mechanism per CSR.
- A CSR carries no validity dates and no serial. Those are chosen by the
signer, so -days on req -new is ignored unless -x509 is also present.
- Public CAs discard most of your CSR. They keep the public key and often
the SANs, then set the subject, dates, and extensions themselves.
- Wildcards cover one label only. *.example.com matches www.example.com
but not a.b.example.com and not the bare example.com.
- -noenc on a CSR command applies to the key written by -keyout, not to
the CSR itself. CSRs are never encrypted.