Skip to main content

How to Read a Certificate with openssl

· 5 min read
Jagdish Kumawat
Founder @ Dewiride

A certificate is a small text file, but you can't read it by opening it. One openssl command tells you who it's for, who signed it, when it ends and which host names it covers, which answers most TLS questions.

What You Need​

  • A certificate file, usually ending in .pem or .crt. It starts with -----BEGIN CERTIFICATE-----.
  • OpenSSL. It's on macOS and Linux. On Windows, you can run it from any Docker image that has it. The examples here run it inside the MySQL container, so they work everywhere, and use a certificate from a MySQL server.

Step 1: Read the Fields That Matter​

Terminal
docker compose exec mysql openssl x509 -in /var/lib/mysql/server-cert.pem -noout -subject -issuer -dates -ext subjectAltName,basicConstraints

If you have OpenSSL on your computer and the file beside you, that's just openssl x509 -in server-cert.pem -noout -subject -issuer -dates -ext subjectAltName,basicConstraints.

Output
subject=CN=inventory-mysql
issuer=CN=MySQL_Server_9.7.4_Auto_Generated_CA_Certificate
notBefore=Nov 6 06:18:35 2026 GMT
notAfter=Feb 8 06:18:35 2029 GMT
X509v3 Subject Alternative Name:
DNS:localhost, IP Address:127.0.0.1

openssl x509 printing the subject CN=inventory-mysql, the issuer, the notBefore and notAfter dates, and a Subject Alternative Name of DNS and IP Address:127.0.0.1.

Line by line:

LineWhat it tells you
subjectWho the certificate is for
issuerWho signed it, which is the CA
notBefore, notAfterWhen it starts and ends
Subject Alternative NameThe host names and IP addresses it's valid for
CA:TRUE in Basic ConstraintsIt can sign other certificates. Shown here only if the certificate has that extension

The options: x509 works with certificates, -in names the file, and -noout stops it printing the certificate back at you. Each of the others asks for one field.

Step 2: Recognize Each Kind of Certificate​

Here's a server certificate that MySQL generated by itself. It has no Subject Alternative Name, and CA:FALSE:

Output
subject=CN=MySQL_Server_9.7.4_Auto_Generated_Server_Certificate
issuer=CN=MySQL_Server_9.7.4_Auto_Generated_CA_Certificate
notBefore=Nov 6 06:03:38 2026 GMT
notAfter=Nov 3 06:03:38 2036 GMT
X509v3 Basic Constraints: critical
CA:FALSE

And here's the CA that signed it. Its subject and issuer are the same, because a root CA signs itself, and it says CA:TRUE:

Output
subject=CN=MySQL_Server_9.7.4_Auto_Generated_CA_Certificate
issuer=CN=MySQL_Server_9.7.4_Auto_Generated_CA_Certificate
notBefore=Nov 6 06:03:38 2026 GMT
notAfter=Nov 3 06:03:38 2036 GMT
X509v3 Basic Constraints: critical
CA:TRUE

So a certificate's issuer should equal its CA's subject. When a connection fails with a message about the CA, comparing those two lines is the first check.

Step 3: See Everything​

-text prints the whole certificate. It's long, so here's the top of it:

Terminal
docker compose exec mysql openssl x509 -in /var/lib/mysql/server-cert.pem -noout -text
Output (the start)
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
6d:2d:03:59:af:21:f3:94:13:be:fc:1f:e8:ec:b8:da:d4:dc:61:0f
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=MySQL_Server_9.7.4_Auto_Generated_CA_Certificate
Validity
Not Before: Nov 6 06:18:35 2026 GMT
Not After : Feb 8 06:18:35 2029 GMT
Subject: CN=inventory-mysql

Step 4: Check It Against Its CA​

openssl verify does the check a client would do with a CA file:

Terminal
docker compose exec mysql openssl verify -CAfile /var/lib/mysql/ca.pem /var/lib/mysql/server-cert.pem /var/lib/mysql/client-cert.pem
Output
/var/lib/mysql/server-cert.pem: OK
/var/lib/mysql/client-cert.pem: OK

openssl verify printing OK for the server's and the client's certificates against the CA file.

Step 5: Check Whether It's About to End​

-checkend takes a number of seconds. 2,592,000 seconds is 30 days:

Terminal
docker compose exec mysql openssl x509 -in /var/lib/mysql/server-cert.pem -noout -checkend 2592000
Output
Certificate will not expire

For a certificate that ended in 2021, it says:

Output
Certificate will expire

It also sets its exit code, so a script can act on the answer: 0 if it won't end in that time, and 1 if it will.

Common Mistakes​

MistakeWhat happensDo this instead
Pointing -in at the private keyCould not find certificate from server-key.pemA certificate starts with BEGIN CERTIFICATE
Reading only subjectClients look at the SAN firstUse -ext subjectAltName too
Comparing issuer with the wrong fileYou blame the wrong certificateCompare it with the CA's subject

Troubleshooting​

SymptomLikely causeFix
No extensions in certificateIt has none of the extensions you asked forThat's an answer, not an error
error 79 at 1 depth lookup: invalid CA certificateThe CA isn't marked as oneThe fix
error 20 at 0 depth lookup: unable to get local issuer certificateThat CA didn't sign itCompare issuer with the CA's subject
error 10 at 0 depth lookup: certificate has expiredIt has endedCheck notAfter

Conclusion​

openssl x509 -noout -subject -issuer -dates -ext subjectAltName answers most certificate questions in one command. openssl verify then checks it the way a client would.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.