Overview

openssl is the Swiss-army knife for certificates, keys, and TLS debugging. The command surface is large; this card covers the 20 % of commands that handle 80 % of real tasks: key generation, self-signed certs, reading existing certs, live server testing, and format conversion. For SSH key management patterns, see ssh-config.

Generate keys

Prefer Ed25519 for SSH; RSA 4096 or ECDSA P-256 for TLS.

CommandKey typeNotes
openssl genrsa -out key.pem 4096RSA 4096Widely supported; larger than needed for modern TLS.
openssl ecparam -name prime256v1 -genkey -noout -out ec.keyECDSA P-256Preferred for TLS; smaller and faster than RSA 2048.
openssl genpkey -algorithm ed25519 -out ed.keyEd25519Best for SSH; not all TLS stacks support it yet.
openssl rsa -in key.pem -pubout -out pub.pemExtract public keyFrom an existing RSA private key.
openssl ec -in ec.key -pubout -out ec_pub.pemExtract public keyFrom an existing EC private key.

Never commit a private key to version control. Store secrets via github-secrets or a secrets manager.

Generate certificates

CommandWhat it creates
openssl req -new -key key.pem -out csr.pemCertificate Signing Request (CSR); submit to a CA.
openssl req -x509 -new -nodes -key key.pem -sha256 -days 365 -out cert.pemSelf-signed cert; not trusted by browsers, but fine for local dev and mutual TLS.
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodesGenerate key and self-signed cert in one step.
openssl req -new -newkey ec:<(openssl ecparam -name prime256v1) -keyout ec.key -out ec.csr -nodesEC key and CSR together.
# Self-signed with Subject Alternative Names (required by Chrome/Firefox)
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \
  -keyout localhost.key -out localhost.crt \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

Inspect certificates and keys

Read without modifying.

CommandWhat it shows
openssl x509 -in cert.pem -text -nooutFull certificate details: subject, issuer, validity, SANs, extensions.
openssl x509 -in cert.pem -noout -datesnotBefore and notAfter expiry dates only.
openssl x509 -in cert.pem -noout -subject -issuerSubject and issuer one-liners.
openssl x509 -in cert.pem -noout -fingerprint -sha256SHA-256 fingerprint for pinning or comparison.
openssl req -in csr.pem -text -nooutInspect a CSR before submitting.
openssl rsa -in key.pem -checkValidate an RSA private key.
openssl verify -CAfile ca.pem cert.pemVerify cert against a CA bundle.
`openssl crl2pkcs7 -nocrl -certfile chain.pemopenssl pkcs7 -print_certs -noout`

Test live TLS connections

CommandWhat it tests
openssl s_client -connect host:443Full TLS handshake; dumps certificate chain and cipher chosen.
openssl s_client -connect host:443 -servername hostEnable SNI (required for virtual-hosted HTTPS).
openssl s_client -connect host:443 -tls1_3Force TLS 1.3 only.
openssl s_client -connect host:443 -cipher ECDHE-RSA-AES256-GCM-SHA384Test a specific cipher suite.
openssl s_client -starttls smtp -connect host:587STARTTLS for SMTP (also works with imap, pop3, ftp).
echo Q | openssl s_client -connect host:443 2>/dev/null | openssl x509 -noout -datesCheck expiry of a live server’s cert without saving it.

Convert and combine formats

ConversionCommand
PEM to DERopenssl x509 -in cert.pem -outform DER -out cert.der
DER to PEMopenssl x509 -in cert.der -inform DER -out cert.pem
PEM to PKCS#12openssl pkcs12 -export -out bundle.p12 -inkey key.pem -in cert.pem -certfile chain.pem
PKCS#12 to PEMopenssl pkcs12 -in bundle.p12 -out all.pem -nodes
Combine cert and chaincat cert.pem chain.pem > fullchain.pem
Extract cert from PKCS#12openssl pkcs12 -in bundle.p12 -nokeys -out cert.pem

Common gotchas

  • openssl x509 -text output uses Subject Alternative Name for the hostnames browsers check. The Common Name field is ignored by all modern browsers; put the hostname in the SAN extension.
  • Self-signed certs without a SAN cause Chrome and Firefox to reject them even on localhost. Always include -addext "subjectAltName=DNS:localhost".
  • openssl s_client exits after the handshake unless you send data. Pipe echo Q | or printf "HEAD / HTTP/1.0\r\n\r\n" | to get the full output.
  • Key and certificate pairing: openssl x509 -noout -modulus -in cert.pem | md5sum and openssl rsa -noout -modulus -in key.pem | md5sum must match. Mismatches cause nginx/Apache to refuse to start.
  • openssl pkcs12 -export without -legacy fails on OpenSSL 3 when importing into older Java or Windows tools. Add -legacy for compatibility with old importers.
  • Default days for CSR signing is 30 in some openssl builds. Always set -days explicitly.