OpenSSL commands and key formats, explained without the man page
Nobody remembers OpenSSL flags. The commands are order-sensitive, the format names overlap, and the error messages are famously unhelpful. Here is the short version that covers most day-to-day work.
The formats
- **PEM** is base64 text wrapped in `-----BEGIN ...-----` headers. It is what most servers want.
- **DER** is the same data in raw binary. Java and Windows tooling often prefer it.
- **PKCS#8** is the modern container for private keys (`BEGIN PRIVATE KEY`). PKCS#1 is the older RSA-specific form (`BEGIN RSA PRIVATE KEY`).
- **PKCS#12 / PFX** bundles a key plus its certificate chain in one password-protected file, typically for IIS or client certificates.
- **JWK** is the JSON representation used by OAuth and OIDC providers.
Converting between them changes the envelope, not the key.
Generating a key and a CSR
openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr \
-subj "/C=US/ST=CA/L=San Francisco/O=Example Inc/CN=example.com"`-nodes` means the private key is not encrypted with a passphrase, which is what you want for a key a web server loads unattended. Keep the `.key` file out of version control.
For elliptic curve, swap the key spec for `-newkey ec -pkeyopt ec_paramgen_curve:P-256`. EC keys are smaller and faster; RSA 2048 is still the most compatible.
A self-signed certificate for local development
openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
-keyout dev.key -out dev.crt -subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"The `subjectAltName` extension is not optional. Browsers have ignored the common name for years, so a certificate without SANs is rejected no matter how correct the rest looks.
Inspecting what you already have
openssl x509 -in cert.pem -noout -text
openssl req -in request.csr -noout -subject
openssl s_client -connect example.com:443 -servername example.com </dev/nullThe last one is the fastest way to confirm which chain a server actually serves — misordered or missing intermediates cause more TLS failures than expired certificates do.
Does the key match the certificate?
Compare the public key fingerprints. If the two hashes differ, the pair is mismatched:
openssl x509 -in cert.pem -noout -pubkey | openssl sha256
openssl pkey -in key.pem -pubout | openssl sha256Do it without memorising any of it
The OpenSSL Command Generator builds these commands from a short form, and the JWK to PEM converter handles the format shuffle in your browser using the Web Crypto API. Neither ever sees your private key: the generator only produces command text, and the converter runs locally.