OpenSSL Guide

How to Check an SSL Certificate with OpenSSL: Every Command

OpenSSL can show you almost everything about an SSL certificate: who issued it, when it expires, its fingerprint, its full chain, and whether it validates. This guide collects every command you need, in copy-paste form, for both live websites and local certificate files.
On this page

Every code example on this page will update as you type. Commands become copy-paste ready for your own site.

Check a live website's SSL certificate

To connect to a server and dump its certificate in human-readable form:

openssl s_client -connect example.com:443 -servername example.com \
</dev/null 2>/dev/null | openssl x509 -text -noout

What each part does:

  • s_client -connect example.com:443: opens a TLS connection to the server
  • -servername example.com: sends SNI, so you get the right certificate on shared hosting (don't skip this)
  • </dev/null: closes the connection immediately instead of hanging
  • 2>/dev/null: hides connection noise
  • openssl x509 -text -noout: decodes the certificate into readable text

Typical output (truncated):

Certificate:
Data:
Version: 3 (0x2)
Serial Number: 04:3a:...
Issuer: C=US, O=Let's Encrypt, CN=R13
Validity
Not Before: Jun 10 04:22:11 2026 GMT
Not After : Sep  8 04:22:10 2026 GMT
Subject: CN=example.com
...

The two lines most people are looking for are Issuer (who signed it) and Not After (when it expires).

Prefer not to use the terminal? ChillSSL SSL monitoring watches your certificates automatically and alerts you before they expire. No commands required.

To check a non-standard port (a mail server, database, or admin panel), change the port. Common examples:

openssl s_client -connect mail.example.com:465 </dev/null 2>/dev/null | openssl x509 -noout -dates
openssl s_client -connect mail.example.com:993 </dev/null 2>/dev/null | openssl x509 -noout -dates
openssl s_client -connect mail.example.com:995 </dev/null 2>/dev/null | openssl x509 -noout -dates
openssl s_client -connect app.example.com:8443 </dev/null 2>/dev/null | openssl x509 -noout -dates

Ports 465 (SMTPS), 993 (IMAPS), 995 (POP3S), 8443 and 9443 are common for mail servers and application admin panels.

View a local certificate file with OpenSSL

If the certificate is already on disk in PEM format (the Base64 text format starting with -----BEGIN CERTIFICATE-----), use openssl x509 directly. This is the command behind "openssl view certificate," "openssl read certificate," "openssl show certificate," and "openssl display certificate." They are all the same operation:

openssl x509 -in certificate.pem -text -noout
  • -in certificate.pem: the file to read (.pem, .crt, and .cer are often PEM, but not always (see the DER section below))
  • -text: full human-readable dump
  • -noout: suppress re-printing the encoded certificate block

To dump everything including the Base64 block (useful when you're re-assembling a bundle), drop -noout:

openssl x509 -in certificate.pem -text

Read a DER-encoded certificate (.der, some .crt/.cer files)

Some .crt and .cer files are PEM while others are DER (binary); the file extension alone doesn't tell you which. If openssl x509 complains with unable to load certificate, the file is probably DER. Tell OpenSSL the input format:

openssl x509 -inform der -in certificate.der -text -noout

To convert DER to PEM so other tools can use it:

openssl x509 -inform der -in certificate.der -out certificate.pem

Check SSL certificate expiration with OpenSSL

For just the validity window of a local file:

openssl x509 -in certificate.pem -noout -dates
notBefore=Jun 10 04:22:11 2026 GMT
notAfter=Sep  8 04:22:10 2026 GMT

Only the expiry date:

openssl x509 -in certificate.pem -noout -enddate

Expiry date of a live website:

openssl s_client -connect example.com:443 -servername example.com \
</dev/null 2>/dev/null | openssl x509 -noout -enddate
notAfter=Aug 29 21:41:26 2026 GMT

Test whether a certificate expires within N seconds, handy in scripts and cron jobs. This checks for expiry within 30 days (2,592,000 seconds):

openssl x509 -in certificate.pem -noout -checkend 2592000

It prints Certificate will not expire or Certificate will expire and sets the exit code accordingly, so you can alert on it:

if ! openssl x509 -in certificate.pem -noout -checkend 2592000; then
echo "Renew soon!" | mail -s "SSL expiry warning" [email protected]
fi

Scripts like this work until the server they run on is the thing that breaks. ChillSSL monitors your certificates externally and emails you before expiry. No cron required.

Show specific certificate fields

You rarely need the full dump. Combine -noout with field flags:

Subject (who the certificate is for):

openssl x509 -in certificate.pem -noout -subject

Issuer (who signed it):

openssl x509 -in certificate.pem -noout -issuer

Serial number:

openssl x509 -in certificate.pem -noout -serial

SHA-256 fingerprint (the value shown in browser certificate viewers and in ChillSSL's certificate details):

openssl x509 -in certificate.pem -noout -fingerprint -sha256

On older OpenSSL releases, use openssl dgst -sha256 instead of piping to openssl sha256.

Subject Alternative Names: every domain the certificate actually covers:

openssl x509 -in certificate.pem -noout -ext subjectAltName
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com

Modern browsers ignore the Subject Common Name for hostname validation. The SAN extension determines which hostnames the certificate is valid for. If a browser says the certificate doesn't match the domain, this is the field to check. Coverage is determined by the SAN list, not the subject CN.

Certificate purpose: which uses the certificate is valid for:

openssl x509 -in certificate.pem -noout -purpose
SSL client : Yes
SSL server : Yes
S/MIME signing : No

Useful for diagnosing certificates that fail handshakes because they're not authorised for the intended purpose.

Signature Algorithm: commonly needed when checking whether a certificate uses SHA-256 or an older algorithm:

openssl x509 -in certificate.pem -noout -text | grep "Signature Algorithm"

Flags combine freely:

openssl x509 -in certificate.pem -noout -subject -issuer -dates -fingerprint -sha256

Check the certificate chain with OpenSSL

A valid leaf certificate still throws browser errors if the certificate chain is incomplete. To see every certificate a server actually sends:

openssl s_client -connect example.com:443 -servername example.com \
-showcerts </dev/null

You'll get a numbered chain:

Certificate chain
0 s:CN=example.com
i:C=US, O=Let's Encrypt, CN=R13
1 s:C=US, O=Let's Encrypt, CN=R13
i:C=US, O=Internet Security Research Group, CN=ISRG Root X1
  • s: is the certificate's subject, i: its issuer
  • Entry 0 is the leaf; each following entry should be the issuer of the one above it
  • The exact intermediate label (here CN=R13) varies by CA and changes when CAs rotate their intermediates
  • If entry 1 is missing, the server isn't sending its intermediate. This can cause some browsers, operating systems, and embedded clients to reject the certificate. Fix: How to Fix a Missing Intermediate Certificate

Then scroll to the bottom of the output and check the verdict:

Verify return code: 0 (ok)

Anything other than 0 (ok) means validation failed. Common examples include:

  • 21 (unable to verify the first certificate): missing intermediate
  • 10 (certificate has expired): expired somewhere in the chain
  • 19 (self-signed certificate in certificate chain): untrusted root or self-signed cert

Download a certificate from a website with OpenSSL

To save a site's certificate as a PEM file:

openssl s_client -connect example.com:443 -servername example.com \
</dev/null 2>/dev/null | openssl x509 -out example.com.pem

To capture the full chain instead, use -showcerts and save everything between the BEGIN/END markers. This saves every certificate the server sends, including intermediates:

openssl s_client -connect example.com:443 -servername example.com \
-showcerts </dev/null 2>/dev/null \
| awk '/BEGIN CERT/,/END CERT/' > chain.pem

(In ChillSSL, this is the one-click Download PEM button on any certificate's details page.)

Verify a certificate against a CA bundle

To validate a certificate the way a browser does, checking it chains to a trusted root, OpenSSL needs two things: a trusted root CA (or the system CA store) and any intermediate certificates required to build the chain.

Option A (recommended): supply a root CA file plus any intermediates

openssl verify \
-CAfile root.pem \
-untrusted intermediate.pem \
certificate.pem

-CAfile should point at trusted root CA certificates, not merely a certificate chain. -untrusted supplies intermediate certificates needed to build the chain without treating them as trust anchors.

Success looks like:

certificate.pem: OK

Option B: use the operating system trust store

On Linux, supply intermediates via -untrusted and let OpenSSL find the trusted root in the system store:

openssl verify \
-CApath /etc/ssl/certs \
-untrusted intermediate.pem \
certificate.pem

Or, pointing at a single CA bundle file:

openssl verify \
-CAfile /etc/ssl/certs/ca-certificates.crt \
-untrusted intermediate.pem \
certificate.pem

The exact bundle path depends on your Linux distribution (/etc/ssl/certs/ca-certificates.crt on Debian/Ubuntu; /etc/pki/tls/certs/ca-bundle.crt on RHEL/CentOS).

Check which TLS versions a server supports

Force a specific protocol version to see whether the server accepts it:

openssl s_client -connect example.com:443 -tls1_2 </dev/null
openssl s_client -connect example.com:443 -tls1_3 </dev/null

If the handshake completes, the version is supported. Add -brief (OpenSSL 3.x) to cut through the handshake noise and see just the result:

openssl s_client -connect example.com:443 -brief </dev/null

Testing legacy versions (only do this against your own servers):

openssl s_client -connect example.com:443 -tls1_1 </dev/null

Modern OpenSSL builds often refuse TLS 1.0/1.1 client-side entirely, which is itself a sign those versions should be off. For the difference between the protocols and the certificates, see TLS vs SSL.

Check that a certificate matches its private key

Mismatched key and certificate is a common cause of servers failing to start after renewal. Compare the public keys derived from each:

openssl x509 -in certificate.pem -noout -pubkey | openssl sha256
openssl pkey -in private.key -pubout | openssl sha256

If the two hashes match, the pair belongs together. (This method works for RSA and ECDSA keys alike, unlike the older modulus-comparison trick.)

On older OpenSSL releases, substitute openssl dgst -sha256 for openssl sha256.

Bonus: inspect a CSR before submitting it to a CA:

openssl req -in request.csr -noout -text

Quick reference

TaskCommand
View live site certopenssl s_client -connect host:443 -servername host </dev/null 2>/dev/null | openssl x509 -text -noout
View local PEMopenssl x509 -in cert.pem -text -noout
View DER fileopenssl x509 -inform der -in cert.der -text -noout
Expiry datesopenssl x509 -in cert.pem -noout -dates
Expires in 30 days?openssl x509 -in cert.pem -noout -checkend 2592000
SHA-256 fingerprintopenssl x509 -in cert.pem -noout -fingerprint -sha256
Subject + issueropenssl x509 -in cert.pem -noout -subject -issuer
SAN listopenssl x509 -in cert.pem -noout -ext subjectAltName
Certificate purposeopenssl x509 -in cert.pem -noout -purpose
Full chain from serveropenssl s_client -connect host:443 -servername host -showcerts </dev/null
Verify against bundleopenssl verify -CAfile root.pem -untrusted intermediate.pem cert.pem
Save site cert as PEMopenssl s_client -connect host:443 -servername host </dev/null 2>/dev/null | openssl x509 -out cert.pem
Cert matches key?Compare x509 -pubkey and pkey -pubout hashes
TLS versions (brief)openssl s_client -connect host:443 -brief </dev/null
Signature algorithmopenssl x509 -in cert.pem -noout -text | grep "Signature Algorithm"

Or let monitoring do it for you

These commands are useful for a one-off check. If you are responsible for any of the certificates you are inspecting, ChillSSL SSL monitoring watches them continuously and emails you before expiry. No cron jobs, no manual checks.

Related reading

Start Monitoring With Confidence

Monitor every SSL certificate in your portfolio with intelligent alerts, renewal confirmation, and complete visibility across every site.