Guides
OpenSSL Commands: CSRs, Self-Signed Certificates and Format Conversion
Six commands cover almost every certificate task. The one worth memorising is s_client, because it shows what a server actually presents rather than what you believe you installed.
Run a fresh DomainLens audit and use the report as your priority list.
Generating a key and a CSR
A certificate signing request bundles your public key with the identity you are claiming. The private key never leaves your server — that is the entire security model, so a provider offering to generate it for you is one to decline.
- -nodes means the key is stored unencrypted, so the server can start without a passphrase prompt.
- Browsers have ignored the Common Name for years — every hostname must appear in subjectAltName.
- Guard the .key file: file permissions of 600 and never in version control.
# 2048-bit RSA key plus a CSR, prompting for details
openssl req -new -newkey rsa:2048 -nodes \
-keyout example.com.key -out example.com.csr
# Non-interactive, with subject on the command line
openssl req -new -newkey rsa:2048 -nodes \
-keyout example.com.key -out example.com.csr \
-subj "/C=US/ST=State/L=City/O=Example Inc/CN=example.com"
# With subject alternative names — required by modern
# browsers, which ignore CN entirely
openssl req -new -newkey rsa:2048 -nodes \
-keyout example.com.key -out example.com.csr \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com"
Self-signed certificates
Self-signed certificates are correct for local development and for origin servers behind a proxy that trusts them. They are never correct for a public site, because no browser trusts them and visitors get the same warning as an expired certificate.
# Key and self-signed certificate, valid one year
openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
-keyout local.key -out local.crt \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
# Without the SAN extension, Chrome rejects it outright
# regardless of what CN says.
Inspecting what is actually there
This is the genuinely useful category. Configuration files describe intent; these commands report reality.
The distinction matters more than it sounds. A certificate can be present on disk, referenced correctly in the configuration, and still not be what the server presents — because the process has not reloaded, because another virtual host matched first, or because a proxy in front terminates TLS with a certificate of its own. Only the handshake settles it.
When reading the output, three fields answer most questions: the subject and its alternative names tell you which hostnames are covered, the issuer tells you whether the certificate came from where you expect, and the validity dates tell you whether the problem is expiry or something else entirely.
- -servername is required on shared hosts; without SNI you may be shown a different site's certificate.
- The modulus comparison is the fastest way to diagnose a key/certificate mismatch.
- -showcerts reveals a missing intermediate, which is why a certificate works in one client and fails in another.
# What a live server presents — the important one
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text
# Just the validity dates
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates
# Read a local certificate file
openssl x509 -in cert.pem -noout -subject -issuer -dates
# Read a CSR before submitting it
openssl req -in example.com.csr -noout -text
# Confirm a key matches its certificate — these must match
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5
# Show the full chain the server sends
openssl s_client -connect example.com:443 -showcerts
Converting between formats
Certificate formats differ in encoding rather than content. PEM is base64 text with header lines, DER is the same structure in raw binary, and PKCS#12 is a container that bundles the certificate, its chain and the private key into one password-protected file. Converting between them changes the wrapper, never the certificate itself.
You need this most often when moving between server families. Linux servers want PEM files kept separate; Windows and IIS expect a single PKCS#12 bundle; some appliances and Java keystores want DER. A certificate that "does not work" on a new platform is frequently just the wrong container.
| Format | Extension | Used by |
|---|---|---|
| PEM | .pem .crt .cer | nginx, Apache — base64 text |
| DER | .der .cer | Java, some appliances — binary |
| PKCS#12 | .pfx .p12 | Windows, IIS — bundles key and cert |
| PKCS#7 | .p7b | Chain only, no private key |
# PEM -> PFX (for IIS)
openssl pkcs12 -export -out cert.pfx \
-inkey key.pem -in cert.pem -certfile chain.pem
# PFX -> PEM (extract both parts)
openssl pkcs12 -in cert.pfx -out cert.pem -nokeys
openssl pkcs12 -in cert.pfx -out key.pem -nocerts -nodes
# DER -> PEM
openssl x509 -inform der -in cert.der -out cert.pem
How DomainLens contributes
The s_client commands above answer one question — what is this server presenting right now — and the SSL checker answers it without a terminal, reporting issuer, dates and protocol for any host. For issuing certificates automatically see certbot and Let's Encrypt .
- What is a CSR?
- A certificate signing request: your public key plus the identity you are claiming, signed by your private key. The authority validates it and returns a certificate. The private key never leaves your server.
- Why does Chrome reject my self-signed certificate?
- Usually because it has no subjectAltName. Modern browsers ignore the Common Name entirely and require every hostname in the SAN extension.
- What is the difference between .pem and .crt?
- Usually nothing — both typically hold base64 PEM data and the extension is convention. Check the contents rather than trusting the name.
- How do I check whether a key matches a certificate?
- Compare their moduli with openssl and hash each. Identical hashes mean they belong together; different ones explain why the server refuses to start.