# OpenSSL x509 commands to inspect a certificate

> OpenSSL 3.x commands to read a certificate: full text, subject, dates, fingerprint, SANs, expiry checks, remote and DER files, chains, revocation URLs, SCTs.

Source: https://ssl.sh/cookbook/inspect-certificates/
Last updated: 2026-11-10

`openssl x509` reads a certificate and prints the part you ask for: everything with `-text`, or single fields such as the subject, expiry date, fingerprint or SAN list. Add `-noout` so OpenSSL does not echo the PEM back. Examples use the certificate example.com served in November 2026 and a local test chain, with OpenSSL 3.6.1.

If you only have a hostname, start with "Inspect a remote server's certificate" below; to check that the chain is valid rather than only read it, see [verify chains](https://ssl.sh/cookbook/verify-chains/).

## Print the whole certificate

`-text -noout` decodes every field into readable text.

```bash
openssl x509 -in example.com.crt -noout -text
```

```text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            01:ee:e6:aa:bb:52:1d:5e:14:fc:31:5f:d9:98:56:90
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
        Validity
            Not Before: Sep 26 22:49:11 2026 GMT
            Not After : Dec 25 22:56:35 2026 GMT
        Subject: CN=example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            Authority Information Access: 
                CA Issuers - URI:http://i.cf-i.ssl.com/Cloudflare-TLS-I-E3.cer
                OCSP - URI:http://o.cf-i.ssl.com
            X509v3 Subject Alternative Name: 
                DNS:example.com, DNS:*.example.com
            X509v3 Certificate Policies: 
                Policy: 2.23.140.1.2.1
            ...
```

Policy OID `2.23.140.1.2.1` marks a domain-validated certificate (`2.23.140.1.2.2` is OV, `2.23.140.1.1` is EV); see [DV, OV and EV](https://ssl.sh/learn/dv-ov-ev/). The [certificate decoder](https://ssl.sh/tools/certificate-decoder/) shows the same fields in the browser.

## Show subject, issuer, dates and serial

Name the fields you want instead of reading the full dump.

```bash
openssl x509 -in example.com.crt -noout -subject -issuer -dates -serial
```

```text
subject=CN=example.com
issuer=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
notBefore=Sep 26 22:49:11 2026 GMT
notAfter=Dec 25 22:56:35 2026 GMT
serial=01EEE6AABB521D5E14FC315FD9985690
```

`-enddate` alone prints only `notAfter`. Times are always GMT. The serial number is what a CA asks for when you revoke a certificate and what CRLs list. `-nameopt RFC2253` prints names in reverse, comma-only form if a tool needs that.

## Show the certificate fingerprint

A fingerprint is a hash of the whole DER certificate and identifies it uniquely.

```bash
openssl x509 -in example.com.crt -noout -fingerprint -sha256
```

```text
sha256 Fingerprint=85:CA:6A:B0:68:E9:BC:CE:88:B6:C4:AA:3C:47:F7:D1:72:28:13:4A:45:7F:87:0D:38:00:E6:22:3A:0D:F0:7A
```

Use SHA-256 for anything new; `-sha1` still works and some old consoles (including the Windows certificate dialog) display SHA-1 thumbprints. The fingerprint changes on every renewal, so pin public keys rather than certificate fingerprints if you pin at all.

## Show the SANs and other extensions

`-ext` (OpenSSL 1.1.1+) prints selected extensions by name, comma-separated.

```bash
openssl x509 -in example.com.crt -noout -ext subjectAltName,keyUsage,extendedKeyUsage
```

```text
X509v3 Subject Alternative Name: 
    DNS:example.com, DNS:*.example.com
X509v3 Extended Key Usage: 
    TLS Web Server Authentication
X509v3 Key Usage: critical
    Digital Signature
```

Other useful names are `basicConstraints`, `authorityInfoAccess`, `crlDistributionPoints`, `certificatePolicies` and `ct_precert_scts`. An EKU list that still includes `TLS Web Client Authentication` matters for [mTLS](https://ssl.sh/learn/mtls/): the Chrome Root Program is removing clientAuth from publicly trusted TLS hierarchies (phase-out of multi-purpose hierarchies starts June 15, 2026; subscriber certificates issued from March 15, 2027 must assert only serverAuth).

## Check whether a hostname or IP matches

`-checkhost` and `-checkip` apply the same matching rules a TLS client uses.

```bash
openssl x509 -in example.com.crt -noout -checkhost www.example.com
openssl x509 -in example.com.crt -noout -checkhost a.b.example.com
openssl x509 -in selfsigned.crt -noout -checkip 203.0.113.10
```

```text
Hostname www.example.com does match certificate
Hostname a.b.example.com does NOT match certificate
IP 203.0.113.10 does match certificate
```

This explains [NET::ERR_CERT_COMMON_NAME_INVALID](https://ssl.sh/errors/net-err-cert-common-name-invalid/) quickly: a wildcard covers exactly one label, and an IP is matched only against IP-type SAN entries.

## Check whether a certificate expires soon

`-checkend N` tests whether the certificate is still valid N seconds from now and sets the exit status.

```bash
openssl x509 -in example.com.crt -noout -checkend 2592000; echo "exit=$?"   # 30 days
openssl x509 -in example.com.crt -noout -checkend 8640000; echo "exit=$?"   # 100 days
```

```text
Certificate will not expire
exit=0
Certificate will expire
exit=1
```

Exit status 0 means still valid at that point, 1 means expired by then. With public certificate lifetimes falling to 200 days from March 15, 2026 and to 47 days by 2029 ([timeline](https://ssl.sh/timeline/certificate-validity/)), a `-checkend` alarm in cron is a cheap safety net next to [automated renewal](https://ssl.sh/learn/automate-certificate-renewal/).

## Inspect a remote server's certificate

Pipe `s_client` into `x509`; `-servername` sends SNI so you get the right certificate on shared hosts.

```bash
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates
```

```text
subject=CN=example.com
issuer=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
notBefore=Sep 26 22:49:11 2026 GMT
notAfter=Dec 25 22:56:35 2026 GMT
```

`echo |` closes the connection immediately instead of waiting for input. To test a specific server behind a CDN or load balancer, connect to its IP (`-connect 203.0.113.10:443`) and keep `-servername example.com`. More connection options are in [test connections](https://ssl.sh/cookbook/test-connections/).

## Read a DER certificate

Binary `.cer` or `.der` files need `-inform DER` on OpenSSL 1.1.1; OpenSSL 3.x usually detects them automatically.

```bash
openssl x509 -in example.com.der -inform DER -noout -subject
file example.com.der example.com.crt
```

```text
subject=CN=example.com
example.com.der: Certificate, Version=3
example.com.crt: PEM certificate
```

If you get `Could not read certificate` or `no start line`, the file is probably DER, PKCS#7 or PKCS#12 rather than PEM. [Convert formats](https://ssl.sh/cookbook/convert-formats/) explains how to tell them apart.

## List every certificate in a chain file

`x509` stops after the first certificate, so route bundles through `pkcs7 -print_certs`.

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

```text
subject=CN=example.com
issuer=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3

subject=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
issuer=C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2

subject=C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2
issuer=C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
```

Each certificate's issuer should be the next certificate's subject; a gap means a [missing intermediate](https://ssl.sh/errors/missing-intermediate-certificate/). `openssl storeutl -noout -certs fullchain.pem` (3.0+) counts the certificates, and adding `-text` dumps them all.

## Inspect each certificate a server sends

`-showcerts` prints the full chain; split it into files to run any `x509` command on each.

```bash
echo | openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null \
  | awk '/BEGIN CERT/{n++} /BEGIN CERT/,/END CERT/{print > ("cert-" n ".pem")}'
for f in cert-*.pem; do openssl x509 -in "$f" -noout -subject -enddate; done
```

```text
subject=CN=example.com
notAfter=Dec 25 22:56:35 2026 GMT
subject=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
notAfter=May 27 19:49:44 2035 GMT
subject=C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2
notAfter=Oct 17 17:02:22 2037 GMT
```

The summary lines at the top of `s_client -showcerts` output (`0 s:` subject, `i:` issuer, `a:` key and signature algorithm, `v:` validity) give the same overview without splitting. A server should send the leaf and intermediates; sending the root is harmless but wasted bytes.

## Show the public key algorithm and size

Extract the public key and print its header, or grep the full text.

```bash
openssl x509 -in example.com.crt -noout -pubkey | openssl pkey -pubin -noout -text | head -1
openssl x509 -in example.com.crt -noout -text | grep -E "Public Key Algorithm|NIST CURVE"
```

```text
Public-Key: (256 bit)
            Public Key Algorithm: id-ecPublicKey
                NIST CURVE: P-256
```

`rsaEncryption` with `(2048 bit)` is RSA; `id-ecPublicKey` with a curve name is ECDSA. To compare the key with a private key file, see the matching recipe in [generate keys](https://ssl.sh/cookbook/generate-keys/).

## Find the OCSP, CA Issuers and CRL URLs

Revocation and chain-fetching URLs sit in two extensions; `-ocsp_uri` prints only the OCSP URL.

```bash
openssl x509 -in example.com.crt -noout -ocsp_uri
openssl x509 -in example.com.crt -noout -ext authorityInfoAccess,crlDistributionPoints
```

```text
http://o.cf-i.ssl.com
Authority Information Access: 
    CA Issuers - URI:http://i.cf-i.ssl.com/Cloudflare-TLS-I-E3.cer
    OCSP - URI:http://o.cf-i.ssl.com
X509v3 CRL Distribution Points: 
    Full Name:
      URI:http://c.cf-i.ssl.com/ae801ed1c55bb579d79208b0d772acfb8cc3a208.crl
```

An empty `-ocsp_uri` is normal for Let's Encrypt certificates issued after May 2025, because Let's Encrypt removed OCSP URLs and relies on CRLs; see [OCSP and CRL](https://ssl.sh/learn/ocsp-and-crl/). The CA Issuers URL is what browsers use to fetch a missing intermediate. Query these URLs with the recipes in [OCSP and CRL commands](https://ssl.sh/cookbook/ocsp-crl/).

## Read the embedded SCTs

Publicly trusted certificates carry Signed Certificate Timestamps proving they were logged in Certificate Transparency.

```bash
openssl x509 -in example.com.crt -noout -ext ct_precert_scts
```

```text
CT Precertificate SCTs: 
    Signed Certificate Timestamp:
        Version   : v1 (0x0)
        Log ID    : 94:4E:43:87:FA:EC:C1:EF:81:F3:19:24:26:A8:18:65:
                    01:C7:D3:5F:38:02:01:3F:72:67:7D:55:37:2E:19:D8
        Timestamp : Sep 26 22:59:12.866 2026 GMT
        Extensions: none
        Signature : ecdsa-with-SHA256
    Signed Certificate Timestamp:
        ...
```

Chrome and Safari require SCTs from multiple logs for a public certificate to be trusted; private CA certificates have none and do not need them. The Log ID identifies the log. Search the logs for every certificate issued for your domain with [CT search](https://ssl.sh/tools/ct-search/), and read [Certificate Transparency](https://ssl.sh/learn/certificate-transparency/) for the policy details.
