I’ve been using OpenSSL for years and I still look things up. Not because the tool is bad — it’s incredibly powerful — but because the syntax is inconsistent and there are so many subcommands that it’s hard to keep everything in your head at once. This is my personal list of commands I reach for regularly, annotated with the things I always forget.
Checking a Certificate File
The command I run more than any other:
openssl x509 -in certificate.crt -text -noout
This prints everything: the subject, issuer, validity dates, SANs, key usage extensions, signature algorithm — all of it. -noout suppresses the re-output of the encoded certificate, so you just get the human-readable dump.
If I only care about the expiry date:
openssl x509 -in certificate.crt -noout -dates
This gives notBefore and notAfter on two clean lines. I use this in monitoring scripts constantly.
Checking a Remote Certificate
You don’t need to download anything to inspect a live certificate:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -text -noout
The -servername flag is important for SNI — without it, servers with multiple virtual hosts might send back the wrong certificate. The </dev/null part tells s_client not to wait for stdin input, so it exits immediately after the handshake.
I use a shorter version when I just want the dates on a remote cert:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
Verifying a Certificate Matches Its Private Key
This is something I need during deployments. If the cert and key don’t match, Nginx or Apache will refuse to start (or worse, start and then behave unexpectedly).
openssl x509 -noout -modulus -in certificate.crt | md5sum
openssl rsa -noout -modulus -in private.key | md5sum
If both MD5 hashes match, the key and certificate are a pair. If they don’t match, you have the wrong key for that cert. Simple, but I’ve saved myself from bad deployments with this check.
For ECDSA keys:
openssl x509 -noout -pubkey -in certificate.crt | md5sum
openssl ec -pubout -in ec.key 2>/dev/null | md5sum
Checking a Certificate Chain
When you have a fullchain file (certificate + intermediates bundled together), you can inspect all the certs in it:
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout
This dumps the subject and issuer of each certificate in the bundle, in order. A correct chain should go from your domain cert → intermediate CA → root CA.
Alternatively, just count the certs in the file:
grep -c "BEGIN CERTIFICATE" fullchain.pem
Should be at least 2 for most commercial certs.
Verifying the Chain of Trust
openssl verify -CAfile chain.pem certificate.crt
If everything is correct, you get certificate.crt: OK. If the chain is incomplete or the root isn’t trusted, you’ll see an error. You can also use the system’s trust store:
openssl verify -CApath /etc/ssl/certs certificate.crt
Generating a Private Key
RSA 2048:
openssl genrsa -out private.key 2048
RSA 4096 (slower, but some compliance frameworks require it):
openssl genrsa -out private.key 4096
ECDSA P-256:
openssl ecparam -name prime256v1 -genkey -noout -out ec.key
Converting Between Certificate Formats
For a deeper look at the different certificate formats (PEM, DER, PFX, CRT), see SSL Certificate Formats Explained. The Certificate Converter tool can also handle conversions without the command line.
PEM to DER:
openssl x509 -outform der -in cert.pem -out cert.der
DER to PEM:
openssl x509 -inform der -in cert.der -out cert.pem
PEM to PKCS#12 (PFX), with private key:
openssl pkcs12 -export -out cert.pfx -inkey private.key -in certificate.crt -certfile chain.pem
Extract PEM from PKCS#12:
openssl pkcs12 -in cert.pfx -out cert.pem -nodes
The -nodes flag skips encrypting the output key. Without it, OpenSSL will ask you to set a passphrase on the extracted key.
Testing TLS Configuration
Check which TLS versions and ciphers a server supports:
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
If the connection fails with -tls1_2, the server doesn’t support TLS 1.2 (unlikely but worth testing). I also use this to verify that TLS 1.0 and 1.1 are properly disabled on servers I’ve configured:
openssl s_client -connect example.com:443 -tls1_1
# Should return: no peer certificate available + handshake failure
Decoding a CSR
To inspect what’s inside a Certificate Signing Request before submitting it (for the full CSR generation workflow, see How to Generate a CSR the Right Way):
openssl req -text -noout -verify -in request.csr
This prints all fields and verifies the CSR signature. Always worth running before sending to a CA.
Checking an OCSP Response
Online Certificate Status Protocol lets you check if a cert has been revoked. Most CAs include the OCSP URL in the certificate itself:
# Get the OCSP URL from the cert
openssl x509 -in cert.pem -noout -text | grep "OCSP"
# Query the OCSP responder
openssl ocsp -issuer chain.pem -cert cert.pem -url http://ocsp.example.com -resp_text
I don’t run OCSP checks manually very often, but when troubleshooting revocation issues it’s invaluable.
A Few Flags I Always Forget
-nodes— no DES encryption (i.e., no passphrase) on output key-noout— don’t print the encoded base64 certificate in output-text— print human-readable content-inform/-outform— specify input/output format (PEM or DER)-servername— set the SNI hostname ins_client-showcerts— ins_client, show the full certificate chain, not just the end-entity cert
Batch Expiry Check Script
Something I’ve used for years — a quick script to check expiry on all .crt files in a directory:
#!/bin/bash
for cert in /etc/ssl/certs/*.crt; do
expiry=$(openssl x509 -noout -enddate -in "$cert" 2>/dev/null | cut -d= -f2)
echo "$cert: $expiry"
done
Not fancy, but it gets the job done. For more systematic certificate monitoring, I’ve been using crtmgr.com which tracks expiry dates with alerts — much better than cron jobs that pipe to email.
OpenSSL’s man pages are dense but complete. Once you know the structure (subcommand → flags → in/out files), a lot of things start making sense. The hardest part is just remembering which subcommand does what — that’s what this cheatsheet is for.