# OpenSSL Certificate Inspection and s_client Cheatsheet This is a plain-text copy of a cheatsheet published by Ellington Technologies, made for pasting into an AI assistant. It's generated from the same source file as the web page. If the two ever differ, the web page is correct: https://jeremiahellington.com/resources/cheatsheets/openssl-certificate-inspection - Source (authoritative web version): https://jeremiahellington.com/resources/cheatsheets/openssl-certificate-inspection - Author: Jeremiah Ellington - Published: 2026-10-28 - Last updated: 2026-10-29 - Last reviewed: 2026-10-28 - Next scheduled review: 2027-04-30 - Applies to: OpenSSL 3.5 LTS on Linux or macOS. Checked against the OpenSSL 3.5 manual pages (docs.openssl.org/3.5) on 2026-10-27, not run against a live server; other 3.x releases may differ in detail OpenSSL commands for reading certificates, requests, CRLs and PFX files, checking a chain, matching a key to its certificate, and testing a live TLS server with s_client, organised around four everyday jobs. --- Every example uses made-up people, names and addresses: `www.example.com`, `mail.example.com`, `dc01.corp.example.com` and the documentation address `192.0.2.10`. Use files from your own test system, never someone else's server or key. Everything here was **checked against the OpenSSL 3.5 manual pages, not lab-tested** (October 27, 2026). ## OpenSSL: four everyday jobs The next four sections each walk through one common job: renewing a certificate with a new key and request, finding out why a site shows the wrong certificate or an incomplete chain, packing a certificate into a PFX for a Windows server, and checking an LDAPS or mail server's certificate against the CA's CRL. Each one starts with a short situation, finds out what's going on with read-only commands, makes the change (each step labelled), confirms it worked, and lists what to try if it didn't. A quick-reference table closes each section. > **Important:** > These four sections were checked against the OpenSSL 3.5 manual pages, not lab-tested. The people and names are made up, and the sample output is illustrative, not captured from a real system. No real certificate, key or serial number appears on this page. Nearly every command only reads. The steps marked **Writes files** create a private key, a PFX or a certificate file; keep key and PFX files secret. ## Renew a certificate: new key, new request ### The situation: www.example.com expires next month Ravi Shah runs the website for example.com. The certificate on `www.example.com` expires in four weeks, and the current one is saved as `server.pem`. The new one has to cover `www.example.com` and `example.com`. ### Find out what's going on (read-only) *Read-only* ```bash openssl x509 -in server.pem -noout -text # everything, in readable form openssl x509 -in server.pem -noout -subject -issuer openssl x509 -in server.pem -noout -dates # notBefore and notAfter openssl x509 -in server.pem -noout -ext subjectAltName # the names the certificate covers openssl x509 -in server.pem -noout -ext extendedKeyUsage,keyUsage,basicConstraints openssl x509 -in server.pem -noout -serial openssl x509 -in server.pem -noout -fingerprint -sha256 # without -sha256, x509 uses SHA-1 openssl x509 -in server.cer -inform DER -noout -text # a binary (DER) file openssl x509 -in server.pem -noout -checkend 2592000 && echo "Still valid in 30 days" ``` `-checkend` takes seconds and exits nonzero if the certificate expires within that time, so it works in a monitoring script. *Sample output (illustrative)* ```text $ openssl x509 -in server.pem -noout -dates -ext subjectAltName notBefore=Nov 25 00:00:00 2025 GMT notAfter=Nov 24 23:59:59 2026 GMT X509v3 Subject Alternative Name: DNS:www.example.com, DNS:example.com ``` Look for: the `notAfter` date, and every name the site answers to in the Subject Alternative Name. ### Make the change **Writes files: creates a private key.** Keep the output files out of shared folders, tickets and version control. *Writes files: private keys* ```bash # New 2048-bit RSA key and a CSR with a SAN. The key is encrypted; you'll be asked for a passphrase. openssl req -new -newkey rsa:2048 -keyout www.example.com.key -out www.example.com.csr \ -subj "/CN=www.example.com" \ -addext "subjectAltName = DNS:www.example.com,DNS:example.com" ``` > **Tip:** > `-noenc` (formerly `-nodes`, deprecated since OpenSSL 3.0) writes the key without a passphrase, which a web server often needs. If you use it, the file permissions are the only protection the key has. ### Confirm it worked Check the request before you send it to the CA, then check the issued certificate matches the key. *Read-only* ```bash openssl req -in www.example.com.csr -noout -text -verify # check the CSR's signature, then show it ``` Read-only, but these commands read the private key. Compare the hashes: if all three match, the key, the certificate and the request belong together. *Read-only (reads the private key, prints only public parts)* ```bash openssl x509 -in www.example.com.pem -noout -pubkey | openssl sha256 openssl pkey -in www.example.com.key -pubout | openssl sha256 openssl req -in www.example.com.csr -noout -pubkey | openssl sha256 ``` ### If it didn't work - **The hashes don't match.** The certificate was issued for a different request, or you're holding an old key. Find the key that made this CSR, or request again with the key you have. - **You want to see inside the key.** `openssl pkey -in server.key -text` prints the private key's components. Don't run it where the output could be logged or pasted into a ticket. `-pubout` limits the output to the public half. ### Quick reference: renew a certificate | Command | What it does | Read-only or changes something | | --- | --- | --- | | `openssl x509 -in server.pem -noout -text` | Shows the whole certificate | Read-only | | `openssl x509 -in server.pem -noout -dates` | Shows notBefore and notAfter | Read-only | | `openssl x509 -in server.pem -noout -ext subjectAltName` | Shows the names the certificate covers | Read-only | | `openssl x509 -in server.pem -noout -fingerprint -sha256` | SHA-256 fingerprint (SHA-1 without `-sha256`) | Read-only | | `openssl x509 -in server.pem -noout -checkend 2592000` | Exits nonzero if it expires within 30 days | Read-only | | `openssl req -new -newkey rsa:2048 -keyout ... -out ...` | Creates a private key and a CSR | Writes files (private key) | | `openssl req -in request.csr -noout -text -verify` | Checks the CSR's signature, then shows it | Read-only | | `openssl pkey -in server.key -pubout \| openssl sha256` | Hashes the key's public half, to match it | Read-only (reads the private key) | ## Find out why a site shows the wrong certificate ### The situation: one server of two is wrong Ravi's new certificate is live, but some visitors to `www.example.com` still get a certificate warning. The site runs on two servers behind DNS, and one of them is at `192.0.2.10`. Ravi needs to know which server is wrong, and how. ### Find out what's going on (read-only) Read-only, but it connects over the network. Only test servers you run or are allowed to test. *Read-only (connects over the network)* ```bash openssl s_client -connect www.example.com:443 -servername www.example.com /dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_2 **Note:** > OpenSSL itself ships no trusted roots. Many Linux distributions supply a system store and configure OpenSSL to use it, so `openssl verify server.pem` with no `-CAfile` uses whatever your distribution provides. ### Confirm it worked *Read-only (connects over the network)* ```bash openssl s_client -connect 192.0.2.10:443 -servername www.example.com \ -verify_return_error -verify_hostname www.example.com /dev/null | openssl x509 -out dc01.pem ``` Everything else in this step only reads. *Read-only (connects over the network)* ```bash openssl s_client -connect dc01.corp.example.com:636 -servername dc01.corp.example.com