2026年11月13日

2026年11月13日

Check SSL Certificate Details with openssl: Expiry, SAN, Issuer, Chain

This article is a localized edition of the Japanese original. Read the Japanese original

With the openssl command you can check what is in a certificate file or in the certificate a web server is sending (expiry date, the domain names it covers, the issuer and so on). It is useful for confirming a certificate after renewal and for tracking down the cause when a browser shows a certificate error.

The commands and output in this article were checked with OpenSSL 3.5.7 on Debian 13 against this site's (lightscend.co.jp) Let's Encrypt certificate (as of November 2026). Some options do not exist in older OpenSSL versions, so check yours with openssl version.

Common commands at a glance

What you want to check Command
Everything openssl x509 -in cert.pem -noout -text
Subject, issuer, validity period openssl x509 -in cert.pem -noout -subject -issuer -dates
Expiry date only openssl x509 -in cert.pem -noout -enddate
Domain names (SAN) openssl x509 -in cert.pem -noout -ext subjectAltName
Whether it expires within 30 days openssl x509 -in cert.pem -noout -checkend 2592000
Fingerprint openssl x509 -in cert.pem -noout -fingerprint -sha256
A server's certificate openssl s_client -connect example.com:443 -servername example.com

-noout suppresses output of the certificate itself (the part starting with -----BEGIN CERTIFICATE-----). Without it, the whole certificate is printed after the information you asked for.

Viewing a certificate file

Subject, issuer and validity period

openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -subject -issuer -dates -serial
subject=CN=lightscend.co.jp
issuer=C=US, O=Let's Encrypt, CN=YE2
notBefore=Sep 12 17:13:06 2026 GMT
notAfter=Dec 11 17:13:05 2026 GMT
serial=064F27F3A770A63F14663E5B8D092E13E231
Field Meaning
subject Who the certificate is for. The domain name goes in CN (common name)
issuer The certificate authority (CA) that issued it
notBefore / notAfter Start / end of the validity period (GMT; Japan time is 9 hours ahead)
serial Serial number, used for example when contacting the CA

You can change the date format with -dateopt iso_8601 (it then shows as notAfter=2026-12-11 17:13:05Z).

With Let's Encrypt (Certbot), /etc/letsencrypt/live/your-domain/ contains the following files.

File Contents
cert.pem The server certificate only
chain.pem Intermediate certificate(s)
fullchain.pem Server certificate + intermediates (this is what you configure in the web server)
privkey.pem Private key

openssl x509 reads only the first certificate even if a file contains several. If you point it at fullchain.pem, you see the details of the server certificate at the top.

Domain names covered (SAN)

Browsers match against the domain names in the SAN (Subject Alternative Name), not the CN. -ext is available in OpenSSL 1.1.1 and later.

openssl x509 -in cert.pem -noout -ext subjectAltName
X509v3 Subject Alternative Name: 
    DNS:lightscend.co.jp, DNS:www.lightscend.co.jp

If the domain in the URL you visit is not listed here, the browser shows a certificate error (name mismatch). -ext accepts several extensions separated by commas (for example -ext keyUsage,extendedKeyUsage,basicConstraints).

Everything

openssl x509 -in cert.pem -noout -text

The output begins like this. You can also see the key type (here a 256-bit elliptic-curve key) and the signature algorithm.

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            06:4f:27:f3:a7:70:a6:3f:14:66:3e:5b:8d:09:2e:13:e2:31
        Signature Algorithm: ecdsa-with-SHA384
        Issuer: C=US, O=Let's Encrypt, CN=YE2
        Validity
            Not Before: Sep 12 17:13:06 2026 GMT
            Not After : Dec 11 17:13:05 2026 GMT
        Subject: CN=lightscend.co.jp
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)

Fingerprint

A value that uniquely identifies a certificate, useful for example to check whether two files hold the same certificate. Without -sha256 you get the SHA-1 value.

openssl x509 -in cert.pem -noout -fingerprint -sha256
sha256 Fingerprint=96:59:AA:5B:D9:79:1C:D2:99:69:8B:C8:17:5F:C3:DF:64:2A:75:1B:37:B1:6A:9B:46:81:D8:E6:06:38:B2:EC

DER files

A file with a .der or .cer extension that shows unreadable characters in a text editor is in DER (binary) format. Read it with -inform DER.

openssl x509 -in cert.der -inform DER -noout -subject -dates

Checking whether expiry is near

-checkend seconds checks whether the certificate will have expired after the given number of seconds and reports the result in the exit code.

openssl x509 -in cert.pem -noout -checkend 2592000   # 30 days = 2592000 seconds
echo $?
Result Message Exit code
Does not expire within the period Certificate will not expire 0
Expires within the period (or has already expired) Certificate will expire 1

With the exit code you can write a script that cron runs regularly.

#!/bin/sh
CERT=/etc/letsencrypt/live/example.com/cert.pem
if ! openssl x509 -in "$CERT" -noout -checkend 2592000 >/dev/null; then
    echo "Certificate expires within 30 days: $CERT"
fi

Let's Encrypt certificates are normally renewed automatically by Certbot. If expiry is close and the certificate has not been renewed, check the auto-renewal setup (Setting up automatic certificate renewal with Certbot).

Checking the certificate a web server is sending

If you update the file but do not reload the web server, it keeps sending the old certificate. Check what it actually sends with openssl s_client.

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -enddate
subject=CN=lightscend.co.jp
issuer=C=US, O=Let's Encrypt, CN=YE2
notAfter=Dec 11 17:13:05 2026 GMT
  • -servername sends the domain name you are accessing (SNI). When one server hosts several domains, the server uses this name to choose which certificate to return. OpenSSL 1.1.1 and later send the host name given in -connect automatically, but when you connect by IP address, for example, specify it explicitly with -servername.
  • </dev/null prevents the command from staying connected and waiting for input.

Connection and verification results in one view

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

Part of the output:

CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=lightscend.co.jp
Hash used: SHA256
Signature type: ecdsa_secp256r1_sha256
Verification: OK

Verification: OK means the chain the server sent (including intermediates) could be verified up to a root certificate installed in the OS. On failure, the reason is shown after Verification error:.

Checking the intermediate certificates being sent

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null \
  | grep -E '^ *[0-9]+ s:|^ *i:'
 0 s:CN=lightscend.co.jp
   i:C=US, O=Let's Encrypt, CN=YE2
 1 s:C=US, O=Let's Encrypt, CN=YE2
   i:C=US, O=ISRG, CN=Root YE
 2 s:C=US, O=ISRG, CN=Root YE
   i:C=US, O=Internet Security Research Group, CN=ISRG Root X2
 3 s:C=US, O=Internet Security Research Group, CN=ISRG Root X2
   i:C=US, O=Internet Security Research Group, CN=ISRG Root X1

s: is each certificate's subject and i: its issuer. The order is correct when the issuer of number 0 is the subject of number 1, and so on. If only number 0 appears, the web server is not configured with the intermediate certificates (in Nginx, point it at fullchain.pem instead of cert.pem). For details see What to do when the intermediate certificate is missing.

Listing every certificate in a file

To look at each certificate in a file that holds several, such as fullchain.pem, run:

openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout
subject=CN=lightscend.co.jp
issuer=C=US, O=Let's Encrypt, CN=YE2

subject=C=US, O=Let's Encrypt, CN=YE2
issuer=C=US, O=ISRG, CN=Root YE

Verifying including intermediate certificates

Check whether the server certificate file can be traced through the intermediates to a trusted root certificate.

openssl verify -untrusted chain.pem cert.pem
cert.pem: OK

Pass the intermediate certificate file to -untrusted. The root certificates come from the OS certificate store. If intermediates are missing, it fails with a message like error 20 at 1 depth lookup: unable to get local issuer certificate.

You can check at the same time whether a domain name is included in the SAN.

openssl verify -untrusted chain.pem -verify_hostname example.com cert.pem

If it is not included, you get error 62 at 0 depth lookup: hostname mismatch.

Checking that a certificate and private key match

If the web server refuses to start with a "key mismatch" error, compare the public keys extracted from the certificate and from the private key. If the two hashes are identical, they match. This works for both RSA and elliptic-curve keys.

openssl x509 -in cert.pem -noout -pubkey | openssl sha256
openssl pkey -in privkey.pem -pubout | openssl sha256

To check the contents of a CSR (certificate signing request) before submitting it:

openssl req -in request.csr -noout -subject -verify

Things to watch

  • Never send a private key file (privkey.pem and the like) to anyone or paste it into a chat, even for troubleshooting. It is handled differently from the certificate, which is public information.
  • openssl s_client shows the certificate of the one server you happened to connect to. If several servers sit behind a load balancer or CDN, you may need to check each one.

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲