The OpenSSL Commands Every Engineer Should Know
A practical reference of the OpenSSL commands you'll actually use — for inspecting certificates, verifying chains, testing live TLS connections, and converting between formats. Copy-ready with real examples.
Inspect a certificate
The most common command — decode a PEM file and show its contents in human-readable form:
openssl x509 -in certificate.pem -text -noout
For a DER-encoded certificate:
openssl x509 -in certificate.der -inform DER -text -noout
Show only the most useful fields — subject, issuer, dates, and fingerprint:
openssl x509 -in certificate.pem -noout \ -subject -issuer -dates -fingerprint -sha256
Verify a certificate chain
Verify that a certificate is signed by a specific CA bundle:
openssl verify -CAfile ca-bundle.pem certificate.pem
Verify with an intermediate CA separately:
openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pem
If the chain is valid you'll see certificate.pem: OK. If not, openssl will tell you exactly which link failed — the same error that causes PKIX path building failed in Java.
Test a live TLS connection
The most useful command for debugging live TLS issues:
openssl s_client -connect example.com:443
Show the full certificate chain the server is sending:
openssl s_client -connect example.com:443 -showcerts
Test with SNI (required for virtual hosting — almost always needed):
openssl s_client -connect example.com:443 -servername example.com
Test a specific TLS version:
openssl s_client -connect example.com:443 -tls1_2 openssl s_client -connect example.com:443 -tls1_3
Test mTLS — send a client certificate:
openssl s_client -connect example.com:443 \ -cert client.pem -key client-key.pem \ -CAfile server-ca.pem
Extract certificates from a server
Save just the leaf certificate from a live server:
openssl s_client -connect example.com:443 2>/dev/null \ | openssl x509 -out server.pem
Save every certificate in the chain to separate files:
openssl s_client -connect example.com:443 -showcerts 2>/dev/null \
| awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ print > "cert" NR ".pem" }'
Convert between formats
PEM → DER
openssl x509 -in cert.pem -outform DER -out cert.der
DER → PEM
openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem
PEM → PKCS#12 (bundle with private key)
openssl pkcs12 -export \ -in cert.pem -inkey key.pem \ -certfile intermediate.pem \ -out bundle.p12 -name "my-cert"
PKCS#12 → PEM (extract cert and key)
# Extract certificate openssl pkcs12 -in bundle.p12 -nokeys -out cert.pem # Extract private key (no passphrase on output) openssl pkcs12 -in bundle.p12 -nocerts -nodes -out key.pem
Check expiry dates
Check when a local certificate expires:
openssl x509 -in cert.pem -noout -dates
Check expiry of a live domain directly:
echo | openssl s_client -servername example.com \ -connect example.com:443 2>/dev/null \ | openssl x509 -noout -dates
Check how many days until expiry (returns exit code 1 if expired):
openssl x509 -in cert.pem -noout -checkend 2592000 # checkend value is in seconds — 2592000 = 30 days # exits 0 if cert is valid for that duration, 1 if it will expire
Generate test certificates
Generate a self-signed certificate for local testing:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \ -days 365 -nodes \ -subj "/CN=localhost/O=Test/C=US"
Generate with Subject Alternative Names (required for modern browsers):
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \ -days 365 -nodes \ -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"