OpenSSL Commands I Actually Use — A Practical Cheatsheet

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 in s_client
  • -showcerts — in s_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.

Scroll to Top