How to View a Certificate with OpenSSL (PEM, CER, Chain, Bundle)

Use OpenSSL to view PEM, CRT, CER, chain, bundle, PFX, and P7B certificates. Check expiry, SAN, fingerprint, remote TLS certs, and verify chains.

Published

Updated

Read time 11 min read

Reviewed byDeepak Prasad

How to View a Certificate with OpenSSL (PEM, CER, Chain, Bundle)

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:

bash
# PEM → DER (.cer)
openssl x509 -in cert.pem -outform DER -out cert.cer

# DER → PEM
openssl x509 -in cert.cer -inform DER -out cert.pem

On 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:

bash
file cert.cer
text
cert.cer: Certificate, Version=3

Then read the DER certificate with OpenSSL:

bash
openssl x509 -in cert.cer -inform DER -noout -subject
text
subject=CN=www.example.test

View 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.

bash
openssl x509 -in server.pem -text -noout

The top of the output looks like this:

text
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:

bash
openssl x509 -in cert.pem -noout -purpose
text
SSL client : Yes
SSL client CA : No
SSL server : Yes
SSL server CA : No

Example one-liner output for subject and issuer:

text
subject=CN=www.example.test
issuer=CN=www.example.test
serial=519C596A2C9AE8AC8805F254396AC95490638A5D

Check 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
text
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:7E

Check whether a hostname matches the certificate (uses CN and SAN):

bash
openssl x509 -in cert.pem -noout -checkhost www.example.test
text
Hostname www.example.test does match certificate
Hostname wrong.example.test does NOT match certificate

Test expiry in automation—exit code 0 means the cert is still valid for at least that many seconds:

bash
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):

bash
openssl s_client -connect google.com:443 -servername google.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates
text
subject=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
NOTE
Always pass -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):

bash
openssl s_client -connect mail.example.com:465 -servername mail.example.com </dev/null 2>/dev/null

For 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:

bash
openssl s_client -connect google.com:443 -servername google.com -showcerts </dev/null 2>/dev/null

Look 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:

bash
openssl x509 -in intermediate.pem -noout -subject -issuer

Save 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:

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

Save the full chain the server presents:

bash
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null \
  | awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{print}' > chain.pem
NOTE
If you are extracting a server certificate for Java, save the PEM file first, then import it with keytool. 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:

bash
openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -noout

Example output for a leaf + intermediate + root file:

text
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 CA

Count how many certificates are in the file:

bash
grep -c "BEGIN CERTIFICATE" chain.pem

On OpenSSL 3.x, storeutl also walks a bundle (useful on large system files):

bash
openssl storeutl -noout -text -certs /etc/ssl/certs/ca-certificates.crt | grep "^Certificate:" | wc -l

Split a bundle into separate files when you need to pass one intermediate to -untrusted:

bash
csplit -f cert- -b '%02d.pem' chain.pem '/-----BEGIN CERTIFICATE-----/' '{*}'

Check certificate chain order

A server fullchain.pem should present certificates in this order:

  1. Leaf / server certificate
  2. Intermediate certificate(s)
  3. 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:

bash
openssl crl2pkcs7 -nocrl -certfile fullchain.pem \
  | openssl pkcs7 -print_certs -noout

The 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):

bash
openssl verify -CAfile ca.pem server.pem
text
server.pem: OK

Three-level chain (root → intermediate → leaf)—put the root in -CAfile and the intermediate in -untrusted:

bash
openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pem
text
leaf.pem: OK

Show the built chain on success:

bash
openssl verify -show_chain -CAfile root.pem -untrusted intermediate.pem leaf.pem
text
leaf.pem: OK
Chain:
depth=0: CN=app.example.test (untrusted)
depth=1: CN=Demo Intermediate CA (untrusted)
depth=2: CN=Demo Root CA

When verification fails because the intermediate is missing from your files (same as an incomplete server chain):

text
CN=app.example.test
error 20 at 0 depth lookup: unable to get local issuer certificate
error leaf.pem: verification failed

Fix by adding the missing intermediate to -untrusted or to the -CAfile bundle—not by ignoring the error.

Verify against the Linux system trust store:

bash
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt server.pem

For 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:

bash
openssl req -in request.csr -noout -text
text
Certificate 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

WARNING
Never paste production private keys into online decoders. Use local openssl commands on your own machine, and restrict file permissions (chmod 600).

Inspect an RSA private key:

bash
openssl rsa -in private.key -noout -text

For 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:

bash
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 -sha256

Matching SHA2-256(stdin)= lines mean the certificate and private key belong together:

text
SHA2-256(stdin)= 63d4eba8434cd26af14811417072f31b1cf8e9208de6e9506f6015144f5ad538
SHA2-256(stdin)= 63d4eba8434cd26af14811417072f31b1cf8e9208de6e9506f6015144f5ad538

Older examples compare RSA modulus MD5 hashes. That still works for RSA-only checks:

bash
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa  -noout -modulus -in key.pem  | openssl md5

The 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:

bash
openssl pkcs12 -in cert.pfx -nokeys -info -passin pass:YOUR_PASSWORD

Extract the certificate:

bash
openssl pkcs12 -in cert.pfx -clcerts -nokeys -out cert.pem -passin pass:YOUR_PASSWORD

For a .p7b PKCS#7 file:

bash
openssl pkcs7 -in cert.p7b -print_certs -out bundle.pem

Then 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.

Frequently Asked Questions

1. How do I view the contents of a certificate file with OpenSSL?

Run openssl x509 -in cert.pem -text -noout for PEM or CRT files. For a binary CER file add -inform DER. The output shows subject, issuer, validity dates, public key, extensions, and the signature algorithm.

2. How do I get the certificate from a remote server using OpenSSL?

Run openssl s_client -connect hostname:443 -servername hostname </dev/null 2>/dev/null | openssl x509 -noout -text for the leaf. Add -showcerts to print every certificate the server sends. Save the leaf with openssl x509 -outform PEM; save the chain by capturing all PEM blocks from -showcerts.

3. How do I view all certificates in a PEM bundle?

Run openssl crl2pkcs7 -nocrl -certfile bundle.pem | openssl pkcs7 -print_certs -noout to list subject and issuer for each cert. On OpenSSL 3.x you can also use openssl storeutl -noout -text -certs bundle.pem.

4. How do I verify a certificate chain with OpenSSL?

Use openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pem. Put the trusted root in -CAfile and any intermediate certificates in -untrusted. Add -show_chain to print the built path when verification succeeds.

5. How do I check when an SSL certificate expires?

Run openssl x509 -in cert.pem -noout -dates for notBefore and notAfter, or openssl x509 -in cert.pem -noout -checkend 86400 to test whether it expires within the next 86400 seconds (one day).

6. How do I confirm a certificate matches its private key?

Compare SHA-256 hashes of the public keys: pipe openssl x509 -noout -pubkey and openssl pkey -pubout through openssl dgst -sha256. Matching digests mean the cert and key belong together. Legacy RSA-only checks compare modulus MD5 hashes.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …