How-to guide · Inspect and check
How to inspect a certificate with OpenSSL
In one sentence
You will have read a certificate file or a server's certificate with OpenSSL and found its names, dates, issuer, key and fingerprint.
- Platforms
- Linux
- macOS
- Windows
- Java
- Level
- Beginner · 5 steps
On this page
Before you start
- OpenSSL 1.1.1 or later, ideally 3.x. Linux distributions include it, Git for Windows ships it inside Git Bash, and on macOS you can install it with Homebrew. The
opensslthat comes with macOS is LibreSSL, whose options and output can differ. - The certificate, as a file (
.crt,.cer,.pem,.der) or as a server name such aswww.example.com. - Nothing secret. A certificate is public, so you can read it anywhere. Its private key is not: never paste a key into a website or a ticket.
Most certificate problems (a missing name, an expired date, the wrong issuer) are visible in 30 seconds once you know which line to read.
Steps
1. Find out what kind of file you have
Look at the first line:
head -1 www.crt
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----: a PEM certificate. Go to step 2.- Unreadable binary: probably DER. Step 2 works too; add
-inform DERon OpenSSL 1.1.1. -----BEGIN PRIVATE KEY-----or-----BEGIN RSA PRIVATE KEY-----: this is a key, not a certificate. Keep it to yourself.-----BEGIN CERTIFICATE REQUEST-----: a CSR. Read it withopenssl req -in file -noout -text.- A
.pfxor.p12file: a password-protected bundle. Extract the certificate first with How to convert PFX to PEM.
The file formats appendix explains every label.
2. Print the whole certificate
openssl x509 -in www.crt -noout -text -certopt no_pubkey,no_sigdump
-noout stops OpenSSL from printing the PEM block again, and -certopt no_pubkey,no_sigdump hides the long hex dumps of the key and signature. Here is our test certificate, issued by a private test CA:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
1c:2a:d3:7b:ba:ee:4f:c8:60:76:fa:37:3b:e4:fc:a5:50:c6:2c:a7
Signature Algorithm: ecdsa-with-SHA256
Issuer: C=BE, O=Keystone Demo, CN=Keystone Demo Issuing CA 1
Validity
Not Before: Oct 20 01:42:24 2026 GMT
Not After : Jan 18 01:42:24 2027 GMT
Subject: C=BE, O=Example Shop, CN=www.example.com
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:www.example.com, DNS:example.com
X509v3 Subject Key Identifier:
F5:0F:A7:10:9F:72:62:B2:CE:A6:F6:68:BB:6B:90:9E:94:FA:8F:12
X509v3 Authority Key Identifier:
D4:01:6F:B3:7A:51:AE:4E:B3:A9:1C:AF:B1:1D:6C:40:6A:B7:77:8C
Authority Information Access:
CA Issuers - URI:http://pki.example.com/issuing-ca-1.cer
Read it with these questions in mind:
| Line | The question it answers |
|---|---|
Subject Alternative Name |
Which host names is it valid for? Clients match the name here. |
Validity |
When does it start and end? Times are in GMT. |
Issuer |
Which CA signed it? Must match the subject of the next certificate in the chain. |
Basic Constraints |
Is it a CA (CA:TRUE) or an end-entity certificate (CA:FALSE)? |
Key Usage, Extended Key Usage |
What may the key do? A web server needs TLS Web Server Authentication. |
Authority Key Identifier |
Links to the issuer’s Subject Key Identifier. |
Authority Information Access |
Where to download the issuer’s certificate (and, for some CAs, the OCSP address). |
The Subject Alternative Name (SAN) is the line that matters most. The CN in the subject is not used for host names by modern clients: Chrome ignores the Common Name and requires the hostname in the Subject Alternative Name (since Chrome 58 (April 2017)).
3. Ask one question at a time
For scripts and quick checks, print only the fields you need:
openssl x509 -in www.crt -noout -subject -issuer -dates -serial
openssl x509 -in www.crt -noout -ext subjectAltName,keyUsage,extendedKeyUsage
openssl x509 -in www.crt -noout -fingerprint -sha256
subject=C=BE, O=Example Shop, CN=www.example.com
issuer=C=BE, O=Keystone Demo, CN=Keystone Demo Issuing CA 1
notBefore=Oct 20 01:42:24 2026 GMT
notAfter=Jan 18 01:42:24 2027 GMT
serial=1C2AD37BBAEE4FC86076FA373BE4FCA550C62CA7
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:www.example.com, DNS:example.com
sha256 Fingerprint=67:E1:E5:8B:37:05:E5:60:D5:61:B0:68:B2:A9:29:BF:87:15:FB:B1:22:F6:C8:01:8E:3A:22:2E:59:34:0C:7D
-ext needs OpenSSL 1.1.1 or later. Name formatting differs between versions: OpenSSL 3.0 prints C = BE, O = Example Shop with spaces, while the 3.2 build used here prints them compactly, as above. Add -nameopt RFC2253 if a script needs one stable format.
The fingerprint is not stored in the certificate. OpenSSL computes it as a SHA-256 hash of the whole DER encoding, so it identifies exactly this certificate.
4. Inspect the certificate a server sends
Pipe openssl s_client into openssl x509:
openssl s_client -connect letsencrypt.org:443 -servername letsencrypt.org </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
subject=CN=letsencrypt.org
issuer=C=US, O=Let's Encrypt, CN=YE2
notBefore=Sep 4 14:34:32 2026 GMT
notAfter=Dec 3 14:34:31 2026 GMT
X509v3 Subject Alternative Name:
DNS:cp.letsencrypt.org, DNS:cp.root-x1.letsencrypt.org, DNS:cps.letsencrypt.org, DNS:cps.root-x1.letsencrypt.org, DNS:lencr.org, DNS:letsencrypt.com, DNS:letsencrypt.org, DNS:www.lencr.org, DNS:www.letsencrypt.com, DNS:www.letsencrypt.org
That was the live certificate on 20 October 2026. Three details matter:
-servernamesends the name in SNI, so a server that hosts many sites returns the right certificate. OpenSSL 1.1.1 and later send the-connecthost name automatically, but you need-servernamewhen you connect to an IP address or a load balancer by another name.</dev/nullcloses the connection straight away. Without it,s_clientwaits for you to type.openssl x509reads only the first certificate, which is the server’s own. To see the intermediates as well, follow How to check the certificate chain a server sends.
5. Inspect every certificate in a bundle file
A fullchain.pem holds several certificates, and openssl x509 silently shows only the first. List them all:
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout
subject=C=BE, O=Example Shop, CN=www.example.com
issuer=C=BE, O=Keystone Demo, CN=Keystone Demo Issuing CA 1
subject=C=BE, O=Keystone Demo, CN=Keystone Demo Issuing CA 1
issuer=C=BE, O=Keystone Demo, CN=Keystone Demo Root CA
Each issuer should be the subject of the next certificate down.
Windows and Java alternatives
Without OpenSSL, Windows has certutil, and every JDK has keytool:
certutil -dump www.crt
NotBefore: 2026-10-20 3:42 AM
NotAfter: 2027-01-18 3:42 AM
keytool -printcert -file www.crt
keytool -printcert -sslserver letsencrypt.org:443
Owner: CN=www.example.com, O=Example Shop, C=BE
Issuer: CN=Keystone Demo Issuing CA 1, O=Keystone Demo, C=BE
Serial number: 1c2ad37bbaee4fc86076fa373be4fca550c62ca7
Valid from: Tue Oct 20 03:42:24 CEST 2026 until: Mon Jan 18 02:42:24 CET 2027
Both show local time, while OpenSSL shows GMT: the same certificate reads 01:42 in OpenSSL and 03:42 in Brussels. keytool -printcert -sslserver prints every certificate the server sends, with its SHA-256 fingerprint.
Check it worked
Confirm you read the right certificate in two ways. First, ask OpenSSL whether the name you care about is covered:
openssl x509 -in www.crt -noout -checkhost www.example.com
openssl x509 -in www.crt -noout -checkhost shop.example.com
Hostname www.example.com does match certificate
Hostname shop.example.com does NOT match certificate
Then compare the fingerprint of your file with the one the server presents. If they are equal, the server runs exactly the certificate you inspected:
openssl s_client -connect www.example.com:443 -servername www.example.com </dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256
You can also paste a PEM certificate into the decoder below. It runs in your browser and accepts certificates only, never keys.
If something goes wrong
Could not read certificate from www.key(OpenSSL 3.0) orCould not find certificate from …(3.2): the file is not a certificate. It is usually a key, a CSR or a PFX. Check the first line again (step 1).unable to load certificateon OpenSSL 1.1.1 with a binary file: add-inform DER, or convert it to PEM.s_clienthangs: add</dev/null, or press Ctrl+C.- The server shows a different certificate from the one you expect: check
-servername, and check that the name resolves to the server you think. A wrong default certificate causesNET::ERR_CERT_COMMON_NAME_INVALIDand Python’s hostname mismatch. notAfteris in the past: clients will fail withcertificate has expired. See How to check when a certificate expires.- You only see one certificate in a bundle: that is
openssl x509reading the first one. Use step 5.
Why this works
A certificate is a signed data structure defined in RFC 5280: a list of fields and extensions, followed by the CA’s signature over them. It is stored as DER bytes, and PEM is the same bytes in Base64 between BEGIN and END lines (RFC 7468). openssl x509 decodes that structure into text, so what you read is exactly what every client reads. Anatomy of an X.509 certificate explains each field, and Names and jobs explains SANs, key usage and the CA flag. Hashes and fingerprints explains why a fingerprint identifies a certificate.
Go deeper
- OpenSSL
x509manual: every display option, including-ext,-checkhostand-checkend. - OpenSSL name display options: stable name formats for scripts.
- OpenSSL
s_clientmanual: connecting to servers, SNI and-showcerts. - RFC 5280, section 4.1: the fields of an X.509 certificate.
- Microsoft Learn: certutil: the Windows certificate utility.
- Oracle: keytool:
-printcertand its options.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.