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
-servernamesends 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-connectautomatically, but when you connect by IP address, for example, specify it explicitly with-servername.</dev/nullprevents 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.pemand 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_clientshows 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)