You landed here with a .pem, .crt, .cer, or .p7b file and need to read what is inside—or you need the certificate a live web server actually presents, including intermediates your browser hides. OpenSSL answers both without a GUI decoder: openssl x509 decodes files on disk, and openssl s_client fetches certs over TLS.
This guide covers every common viewing scenario: decode PEM and DER (.cer) files, pull fields like expiry and Subject Alternative Name (SAN), dump a server chain, list every certificate in a bundle, and verify a chain with openssl verify.
Tested on: Ubuntu 26.04 LTS (Resolute Raccoon); kernel 7.0.0-27-generic; OpenSSL 3.5.5.
Quick answer: view a certificate file
| Task | Command |
|---|---|
| View PEM / CRT (full text) | openssl x509 -in cert.pem -text -noout |
View binary DER .cer |
openssl x509 -in cert.cer -inform DER -text -noout |
| PEM → DER | openssl x509 -in cert.pem -outform DER -out cert.cer |
| DER → PEM | openssl x509 -in cert.cer -inform DER -out cert.pem |
| Expiry dates | openssl x509 -in cert.pem -noout -dates |
| Subject | openssl x509 -in cert.pem -noout -subject |
| Issuer | openssl x509 -in cert.pem -noout -issuer |
| Serial number | openssl x509 -in cert.pem -noout -serial |
| SHA-256 fingerprint | openssl x509 -in cert.pem -noout -fingerprint -sha256 |
| SAN names | openssl x509 -in cert.pem -noout -ext subjectAltName |
| Allowed purposes (SSL server/client, CA, …) | openssl x509 -in cert.pem -noout -purpose |
| Hostname match | openssl x509 -in cert.pem -noout -checkhost www.example.com |
| Expires within N seconds | openssl x509 -in cert.pem -noout -checkend N |
| Remote leaf (inspect) | openssl s_client -connect host:443 -servername host </dev/null 2>/dev/null | openssl x509 -noout -text |
| Save remote leaf PEM | openssl s_client -connect host:443 -servername host </dev/null 2>/dev/null | openssl x509 -outform PEM > leaf.pem |
Remote full chain (-showcerts) |
openssl s_client -connect host:443 -servername host -showcerts </dev/null 2>/dev/null |
| Save remote chain PEM | openssl s_client … -showcerts </dev/null 2>/dev/null | awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{print}' > chain.pem |
| List every cert in a bundle | openssl crl2pkcs7 -nocrl -certfile bundle.pem | openssl pkcs7 -print_certs -noout |
| Check bundle / chain order | openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout |
| Count certs in bundle | grep -c "BEGIN CERTIFICATE" bundle.pem |
| Verify chain | openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pem |
| Verify with system CAs | openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt cert.pem |
| View CSR | openssl req -in request.csr -noout -text |
| View RSA private key | openssl rsa -in private.key -noout -text |
| Cert matches key (SHA-256) | See confirm cert and key match |
PKCS#12 (.pfx) info |
openssl pkcs12 -in cert.pfx -nokeys -info -passin pass:PASSWORD |
PKCS#7 (.p7b) to PEM |
openssl pkcs7 -in cert.p7b -print_certs -out bundle.pem |
PEM vs DER: know which format you have
| Extension / look | Format | View command |
|---|---|---|
.pem, .crt (text, BEGIN CERTIFICATE) |
PEM | openssl x509 -in file -text -noout |
.cer (binary, opens as gibberish in an editor) |
DER | openssl x509 -in file -inform DER -text -noout |
.cer (text with BEGIN CERTIFICATE) |
PEM | same as PEM row |
Convert between formats when a tool expects the other:
# PEM → DER (.cer)
openssl x509 -in cert.pem -outform DER -out cert.cer
# DER → PEM
openssl x509 -in cert.cer -inform DER -out cert.pemOn a DER file, the file command may report Certificate, Version=3. If openssl x509 -in cert.cer -text -noout fails, read it with -inform DER.
Check the file type first:
file cert.cercert.cer: Certificate, Version=3Then read the DER certificate with OpenSSL:
openssl x509 -in cert.cer -inform DER -noout -subjectsubject=CN=www.example.testView full certificate details
The -text flag prints subject, issuer, serial number, validity window, public key, extensions (including SAN on modern certs), and signature data. Pair it with -noout so OpenSSL does not re-encode the cert to stdout.
openssl x509 -in server.pem -text -nooutThe top of the output looks like this:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
51:9c:59:6a:2c:9a:e8:ac:88:05:f2:54:39:6a:c9:54:90:63:8a:5d
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=www.example.test
Validity
Not Before: Jul 2 04:29:01 2026 GMT
Not After : Jul 2 04:29:01 2027 GMT
Subject: CN=www.example.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)Scroll further for X509v3 extensions—that is where SAN entries, key usage, and basic constraints appear on CA and server certificates.
Read one field without the full dump
When you only need identity metadata, -noout plus a single flag keeps output short and script-friendly.
| Goal | Command |
|---|---|
| Subject DN | openssl x509 -in cert.pem -noout -subject |
| Issuer DN | openssl x509 -in cert.pem -noout -issuer |
| Serial number | openssl x509 -in cert.pem -noout -serial |
| Certificate purposes | openssl x509 -in cert.pem -noout -purpose |
-purpose shows whether OpenSSL considers the cert valid for SSL server, SSL client, CA signing, and related roles—useful when troubleshooting “wrong cert type” errors:
openssl x509 -in cert.pem -noout -purposeSSL client : Yes
SSL client CA : No
SSL server : Yes
SSL server CA : NoExample one-liner output for subject and issuer:
subject=CN=www.example.test
issuer=CN=www.example.test
serial=519C596A2C9AE8AC8805F254396AC95490638A5DCheck expiry, SAN, fingerprint, and hostname
These flags answer the questions operators ask most often before a renewal or deployment.
| Goal | Command |
|---|---|
| Expiry dates | openssl x509 -in cert.pem -noout -dates |
| SHA-256 fingerprint | openssl x509 -in cert.pem -noout -fingerprint -sha256 |
| SAN extension | openssl x509 -in cert.pem -noout -ext subjectAltName |
| Hostname match | openssl x509 -in cert.pem -noout -checkhost www.example.com |
| Expires within N seconds | openssl x509 -in cert.pem -noout -checkend N |
notBefore=Jul 2 04:29:01 2026 GMT
notAfter=Jul 2 04:29:01 2027 GMT
sha256 Fingerprint=2B:93:4C:A6:60:31:F5:B4:65:CC:CD:FF:04:77:14:6F:07:BF:A0:14:A5:03:56:1C:35:C3:47:93:56:A1:CA:7ECheck whether a hostname matches the certificate (uses CN and SAN):
openssl x509 -in cert.pem -noout -checkhost www.example.testHostname www.example.test does match certificate
Hostname wrong.example.test does NOT match certificateTest expiry in automation—exit code 0 means the cert is still valid for at least that many seconds:
openssl x509 -in cert.pem -noout -checkend 86400 && echo "valid 24h+" || echo "expires within 24h"Get a certificate from a remote server
The canonical way to see what a TLS server presents is openssl s_client. It performs a real handshake and prints certificate details.
Leaf certificate only (common quick check):
openssl s_client -connect google.com:443 -servername google.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -datessubject=CN=*.google.com
issuer=C=US, O=Google Trust Services, CN=WE2
notBefore=Jun 15 08:39:06 2026 GMT
notAfter=Sep 7 08:39:05 2026 GMT-servername (SNI) when the host serves multiple certificates on one IP—without it you may inspect the wrong vhost’s cert.
Non-default ports (LDAPS, SMTPS, custom app):
openssl s_client -connect mail.example.com:465 -servername mail.example.com </dev/null 2>/dev/nullFor STARTTLS protocols (SMTP, IMAP, FTP), add the protocol flag, for example -starttls smtp.
View the certificate chain from a server
Browsers often download missing intermediates automatically; openssl s_client does not. To debug “works in Chrome, fails in curl” chain issues, print every certificate the server sends:
openssl s_client -connect google.com:443 -servername google.com -showcerts </dev/null 2>/dev/nullLook for the Certificate chain section. Each entry shows:
s:— subject (who the cert is for)i:— issuer (who signed it)
The issuer of the leaf should match the subject of the next certificate up. If the chain stops at the leaf with no intermediate, the server is not sending a complete chain—a frequent cause of unable to get local issuer certificate in API clients.
To inspect one cert from the dump, copy a single -----BEGIN CERTIFICATE----- … -----END CERTIFICATE----- block into intermediate.pem and run:
openssl x509 -in intermediate.pem -noout -subject -issuerSave the leaf certificate or full chain
-showcerts prints every certificate the server sends; piping through openssl x509 without it captures only the leaf (the first cert in the handshake).
Save the leaf certificate only:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -outform PEM > leaf.pemSave the full chain the server presents:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null \
| awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{print}' > chain.pemkeytool. See keytool tutorial for Java truststore commands.
View all certificates in a PEM bundle
A bundle file (often ca-bundle.crt, chain.pem, or fullchain.pem) concatenates several PEM certificates back-to-back. To list each one without opening a decoder website:
openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -nooutExample output for a leaf + intermediate + root file:
subject=CN=app.example.test
issuer=CN=Demo Intermediate CA
subject=CN=Demo Intermediate CA
issuer=CN=Demo Root CA
subject=CN=Demo Root CA
issuer=CN=Demo Root CACount how many certificates are in the file:
grep -c "BEGIN CERTIFICATE" chain.pemOn OpenSSL 3.x, storeutl also walks a bundle (useful on large system files):
openssl storeutl -noout -text -certs /etc/ssl/certs/ca-certificates.crt | grep "^Certificate:" | wc -lSplit a bundle into separate files when you need to pass one intermediate to -untrusted:
csplit -f cert- -b '%02d.pem' chain.pem '/-----BEGIN CERTIFICATE-----/' '{*}'Check certificate chain order
A server fullchain.pem should present certificates in this order:
- Leaf / server certificate
- Intermediate certificate(s)
- Optional additional intermediate
Do not put the private key in the chain file. Usually do not include the root CA in the server chain unless your product documentation explicitly requires it.
List subjects and issuers in file order:
openssl crl2pkcs7 -nocrl -certfile fullchain.pem \
| openssl pkcs7 -print_certs -nooutThe issuer of certificate 1 should match the subject of certificate 2. If that link breaks, nginx, Apache, or API clients may report incomplete chain errors even when each file decodes fine on its own.
Verify a certificate chain with openssl verify
Viewing tells you what is in the files; openssl verify tells you whether the chain validates to a trusted root.
Simple two-level chain (root signed the leaf directly):
openssl verify -CAfile ca.pem server.pemserver.pem: OKThree-level chain (root → intermediate → leaf)—put the root in -CAfile and the intermediate in -untrusted:
openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pemleaf.pem: OKShow the built chain on success:
openssl verify -show_chain -CAfile root.pem -untrusted intermediate.pem leaf.pemleaf.pem: OK
Chain:
depth=0: CN=app.example.test (untrusted)
depth=1: CN=Demo Intermediate CA (untrusted)
depth=2: CN=Demo Root CAWhen verification fails because the intermediate is missing from your files (same as an incomplete server chain):
CN=app.example.test
error 20 at 0 depth lookup: unable to get local issuer certificate
error leaf.pem: verification failedFix by adding the missing intermediate to -untrusted or to the -CAfile bundle—not by ignoring the error.
Verify against the Linux system trust store:
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt server.pemFor deeper PKI work after inspection, see create a certificate chain and OpenSSL config locations.
View a Certificate Signing Request (CSR)
A CSR is not a certificate—it is a signed request for one. Inspect it before you send it to a CA:
openssl req -in request.csr -noout -textCertificate Request:
Data:
Version: 1 (0x0)
Subject: CN=www.example.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)Check the subject and SAN sections match what you intended before submitting. To generate a CSR, see OpenSSL generate CSR.
View a private key safely
openssl commands on your own machine, and restrict file permissions (chmod 600).
Inspect an RSA private key:
openssl rsa -in private.key -noout -textFor encrypted keys, add -passin pass:yourpass or let OpenSSL prompt interactively. For EC keys use openssl ec -in key.pem -noout -text.
Confirm certificate and private key match
Before you reload nginx or Apache, confirm the certificate matches the private key—compare public-key SHA-256 digests:
openssl x509 -in cert.pem -noout -pubkey \
| openssl pkey -pubin -outform DER \
| openssl dgst -sha256
openssl pkey -in private.key -pubout -outform DER \
| openssl dgst -sha256Matching SHA2-256(stdin)= lines mean the certificate and private key belong together:
SHA2-256(stdin)= 63d4eba8434cd26af14811417072f31b1cf8e9208de6e9506f6015144f5ad538
SHA2-256(stdin)= 63d4eba8434cd26af14811417072f31b1cf8e9208de6e9506f6015144f5ad538Older examples compare RSA modulus MD5 hashes. That still works for RSA-only checks:
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5The public-key SHA-256 method is clearer and works across more key types than modulus comparison alone.
PKCS#12 (.pfx / .p12) and PKCS#7 (.p7b)
Windows and IIS often hand you a .pfx bundle (cert + key). List contents without importing to a store:
openssl pkcs12 -in cert.pfx -nokeys -info -passin pass:YOUR_PASSWORDExtract the certificate:
openssl pkcs12 -in cert.pfx -clcerts -nokeys -out cert.pem -passin pass:YOUR_PASSWORDFor a .p7b PKCS#7 file:
openssl pkcs7 -in cert.p7b -print_certs -out bundle.pemThen use openssl x509 -text -noout -in bundle.pem on the result, or split the bundle as shown above.
Troubleshooting
| Problem | Likely cause | What to run |
|---|---|---|
unable to load certificate |
Wrong format (DER vs PEM) | Add -inform DER or convert with -outform PEM |
no certificate or crl found |
File is empty, not PEM/DER, or contains unsupported content | Check with file cert.pem, head cert.pem, and confirm it has BEGIN CERTIFICATE |
Expecting: CERTIFICATE |
File is a CSR or key, not a cert | openssl req -text or openssl rsa -text instead |
Empty output from s_client |
Wrong port, firewall, or no TLS | Confirm port; try -tls1_2 |
| Wrong hostname in cert | Missing SNI | Add -servername exact.host.name |
verify error 20 |
Missing intermediate CA | -untrusted intermediate.pem or fix server chain |
verify error 10 |
Expired certificate | openssl x509 -noout -dates -in cert.pem |
openssl x509 shows only the first certificate in a bundle |
openssl x509 reads one certificate at a time |
openssl crl2pkcs7 -nocrl -certfile bundle.pem | openssl pkcs7 -print_certs -noout |
| Public-key SHA-256 mismatch | Cert and key from different pairs | Re-export from the CA or locate the matching key |
| Modulus MD5 mismatch (legacy RSA) | Cert and key from different pairs | Prefer SHA-256 public-key check above |
References
Summary
Use openssl x509 -in file -text -noout to decode PEM and CRT files, and add -inform DER for binary .cer files from Windows. Pull identity fields with -subject, -issuer, and -purpose; check expiry, SAN, fingerprint, and hostname with -dates, -ext subjectAltName, -fingerprint -sha256, and -checkhost. Inspect a remote leaf with openssl s_client … | openssl x509; use -showcerts to view the chain and awk to save it. List bundle contents and check order with openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout, then verify with openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pem. Match a cert to its key with public-key SHA-256 digests before you reload a web server.

