How to check the expiration date of a certificate using openssl command/option explanation
table of contents
Hello. I am a member of the System Solutions Department of Beyond Co., Ltd.
This Beyond blog you are viewing has been converted to HTTPS. Over the past decades, HTTPS has become a huge hit, and the number of HTTP sites has decreased considerably.
At this time, the "SSL certificate" required for HTTPS is generally renewed in one year, so regular renewal is required, but many people use a browser to check the validity period of the SSL certificate.
However, there are probably some people who say, "The browser is indeterminate, so I want to check using a command," or those who use commands to check using a command for reasons such as "The port is not open externally because it is currently under development so I can't check using a browser," but when searching for commands that are only used occasionally, a certain problem arises.
"The command usage and options differ slightly depending on the person, but what are the differences?"
"Even if I hit man, there are so many options that I don't understand."
For such people, I would like to explain the meaning and usage of the options that are often used with the openssl command when checking SSL certificates.
Execution environment
・OS: AlmaLinux8 (WSL2 environment)
・Shell: bash
・OpenSSL: OpenSSL 1.1.1k FIPS 25 Mar 2021
Check “locally” or “remotely” using openssl command
To begin with, the openssl command is a command developed and published by OpenSSL projects, and is usually used by default in mainstream Linux distributions. This command is often possible, but this time it will be used to check the expiration date of an SSL certificate.
Also, when checking using this command, there are two ways to check: "Check the SSL certificate locally" and "Check the SSL certificate remotely from outside."
First, let me explain the former local area.
local environment
Here are some commands that I often use when checking in a local environment.
The openssl command is used to load a locally stored certificate and display the common name, valid start date and expiration date.
$ openssl x509 -noout -subject -dates -in /etc/pki/tls/certs/example.crt
*Output sample subject=CN = exmaple.com *Common name (≒ domain name) notBefore=Mar 31 04:42:17 2022 GMT *Valid start date notAfter=May 2 04:42:16 2023 GMT *Expiration date
x509
When dealing with SSL certificates, use the subcommand "x509" in the "openssl" command.
*"X.509" is the name of the standard format for public key certificates, so it may be easier to remember if you associate it with it.
-in
When running in a local environment, you need to specify the name of the certificate to load, so use this option.
-subject
This option outputs the subject field (where the common name is written) from the imported certificate.
-dates
This option outputs the validity start date and expiration date from the imported certificate.
-noout
This is the option to "Do not output information other than the information specified in other options." If this option is not available, the pre-decrypted certificate loaded by the commands like the one below will also be displayed.
-----BEGIN CERTIFICATE----- MIIGMjCCBRqgAwIBAgIMMGPvI3CXFUjGngZcMA0GCSqGSIb3DQEBCwUAMEwxCzAJ BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSIwIAYDVQQDExlB ~The following dozens of lines are omitted~ -----END CERTIFICATE-----
As an aside, there is also a -nocert option that is limited to not displaying the contents of the certificate.
remote environment
Here are some commands that I often use when checking remotely. The openssl s_client command is used to access the target host, then loads the certificate from it, displaying the common name, valid start date and expiration date.
$openssl s_client -connect beyondjapan.com:443 < /dev/null 2> /dev/null | openssl x509 -noout -subject -dates
*Actual output subject=CN = beyondjapan.com notBefore=Mar 31 04:42:17 2022 GMT notAfter=May 2 04:42:16 2023 GMT
s_client
Use subcommands that provide the client functionality required when communicating with SSL/TLS.
-connect host:port
It's an option for remote (specifying the host and port to connect to), just like you used -in locally to specify a file.
*This time we are using 443 (HTTPS), but you can also specify a port such as SMTP and use it to check the SSL/TLS connection.
< /dev/null
The "openssl s_client" command connects to the specified destination and then goes into the "input waiting state", so none (/dev/null) is entered into the standard input to end the input waiting. If you do not use this, you will need to end the command using ctrl+c, so this is because it will take a lot of time.
*This is not an option, but a specification relating to standard input for Shell (in this environment, bash).
2> /dev/null
This is a standard error output (2) on Linux is outputted to none (/dev/null) and discarded, and prevented it from being displayed on Shell. If you use the previous < /dev/null, an unnecessary Error statement appears, so this is a measure to erase it.
*This is not an option, but a specification concerning the standard output of Shell (in this environment, bash).
| openssl x509 -noout -subject -dates
Use "|" (pipe) to pass it to a command that loads the contents of the SSL certificate received through communication. The command after pipe is almost the same as when it's local, but since the certificate is received by the pipe, the -in option, which specifies the certificate to be loaded, is not used.
*If there is no -in option, the specification of this command (x509) is to process the contents passed to standard input.
Commands and options used by others
command
echo | openssl s_client -connect ~
When checking in a remote environment, I used < /dev/null to end the input wait, but I think that using echo will put the command to standard output on the Shell to take priority, and force it to end up waiting for input. The intent is the same as < /dev/null.
~ | openssl x509 -text | grep "Not"
The -text option will decrypt all the contents of the certificate and output them in text. This is all included in the contents that were individually specified and displayed in other options, so it is used when you want to check all the contents. The output contents are passed to grep via a pipe and output a line containing "Not".
$ openssl s_client -connect beyondjapan.com:443 < /dev/null 2> /dev/null | openssl x509 -text | grep "Not" Not Before: Mar 31 04:42:17 2022 GMT Not After : May 2 04: 42:16 2023 GMT
This outputs the rows for the valid start and expiration dates. The commands are long, but they are simple, so I think they are easy to understand for "people who know them."
However, even though there are dedicated options, I feel like relying on grep will not be able to research options much, leaving my understanding of the openssl command unsuccessfully, so I use the command I presented at the beginning.
Furthermore, when you try to output a domain name (common name), the problem is that the commands will become less readable due to the use of regular expression options.
option
-enddate
This option displays only the expiration date from the loaded certificate. There is also an option called -startdate that displays the valid start date, but since the -dates option means that both options are applied at the same time, I think -dates is fine if you are not particularly particular about it.
-text
As mentioned above, this is an option to display the certificate in text format. The output includes all setting information such as the public key, signature algorithm, issuer, subject name, expiration date, etc.
Patterns without -noout
In this case, the undecrypted certificate requested by the command is displayed as is, and the expiration date specified in the option will be displayed. To be honest, I don't look at the contents of undecrypted certificates, so it's easier to read if I wear them.
The command output results show the word "CERTIFICATE", which clearly shows that you are "checking the certificate." This may be an advantage.
< /dev/null 2> Pattern without /dev/null
It is intended to be a preceded version of the command using ctrl + c, and it seems to be easy to input manually and readable at a glance, so I think it is intended to prioritize that. I think I like this kind of thing, but I like the pattern I put in, because sometimes I end up entering the next command without quitting the command, causing the output and log to get dirty.
lastly
As I wrote this article, I once again realized that openssl commands are often possible, and there are also a large amount of options, which is very confusing.
This is just a part of what can be done, and the main technology, encryption and authentication methods, is itself extremely logical and profound. I hope that reading this article will help you resolve any resistance or doubts about the openssl command!
Thank you for reading this far.
Next article
Below is how to check the "integrity and verification results," which are often checked in conjunction with the "expiration date."
How to check certificate integrity and verification results with openssl command/option explanation
How to check certificate integrity and verification results with openssl command/option explanation
Reference materials
OpenSSL official manual page for openssl-x509
https://www.openssl.org/docs/manmaster/man1/openssl-x509.html
OpenSSL (ArchWiki)
https://wiki.archlinux.jp/index.php/OpenSSL