Displaying a remote SSL certificate details using CLI tools
Solution 1
You should be able to use OpenSSL for your purpose:
echo | openssl s_client -showcerts -servername gnupg.org -connect gnupg.org:443 2>/dev/null | openssl x509 -inform pem -noout -text
That command connects to the desired website and pipes the certificate in PEM format on to another openssl command that reads and parses the details.
(Note that "redundant" -servername
parameter is necessary to make openssl
do a request with SNI support.)
Solution 2
Basic certificate info
That's my everyday script:
curl --insecure -vvI https://www.example.com 2>&1 | awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }'
Output:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=US; ST=California; L=Los Angeles; O=Verizon Digital Media Services, Inc.; CN=www.example.org
* start date: Dec 10 00:00:00 2021 GMT
* expire date: Dec 9 23:59:59 2022 GMT
* issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5588e1f5ae30)
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
* Connection #0 to host www.example.com left intact
Full certificate info
openssl s_client -connect www.example.com:443 </dev/null 2>/dev/null | openssl x509 -inform pem -text
Solution 3
nmap -p 443 --script ssl-cert gnupg.org
The -p 443
specifies to scan port 443 only. All ports will be scanned if it is omitted, and the certificate details for any SSL service that is found will be displayed. The --script ssl-cert
tells the Nmap scripting engine to run only the ssl-cert
script. From the doc, this script "(r)etrieves a server's SSL certificate. The amount of information printed about the certificate depends on the verbosity level."
Sample output:
Starting Nmap 7.40 ( https://nmap.org ) at 2017-11-01 13:35 PDT
Nmap scan report for gnupg.org (217.69.76.60)
Host is up (0.16s latency).
Other addresses for gnupg.org (not scanned): (null)
rDNS record for 217.69.76.60: www.gnupg.org
PORT STATE SERVICE
443/tcp open https
| ssl-cert: Subject: commonName=gnupg.org
| Subject Alternative Name: DNS:gnupg.org, DNS:www.gnupg.org
| Issuer: commonName=Gandi Standard SSL CA 2/organizationName=Gandi/stateOrProvinceName=Paris/countryName=FR
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2015-12-21T00:00:00
| Not valid after: 2018-03-19T23:59:59
| MD5: c3a7 e0ed 388f 87cb ec7f fd3e 71f2 1c3e
|_SHA-1: 5196 ecf5 7aed 139f a511 735b bfb5 7534 df63 41ba
Nmap done: 1 IP address (1 host up) scanned in 2.31 seconds
Solution 4
Depends on what kind of information you want, but:
openssl s_client -showcerts -connect gnupg.org:443
should give you most, although not as nicely human readable like Chrome presents it.
Solution 5
For completeness: if you have installed on your system Java 7 or higher
keytool -printcert -sslserver $host[:$port]
shows the chain (as served) with nearly all details in a mostly rather ugly format.
Whether you should have Java installed on your system I do not answer.
Related videos on Youtube
Adam Matan
Team leader, developer, and public speaker. I build end-to-end apps using modern cloud infrastructure, especially serverless tools. My current position is R&D Manager at Corvid by Wix.com, a serverless platform for rapid web app generation. My CV and contact details are available on my Github README.
Updated on September 18, 2022Comments
-
Adam Matan over 1 year
In Chrome, clicking on the green HTTPS lock icon opens a window with the certificate details:
When I tried the same with cURL, I got only some of the information:
$ curl -vvI https://gnupg.org * Rebuilt URL to: https://gnupg.org/ * Hostname was NOT found in DNS cache * Trying 217.69.76.60... * Connected to gnupg.org (217.69.76.60) port 443 (#0) * TLS 1.2 connection using TLS_DHE_RSA_WITH_AES_128_CBC_SHA * Server certificate: gnupg.org * Server certificate: Gandi Standard SSL CA * Server certificate: UTN-USERFirst-Hardware > HEAD / HTTP/1.1 > User-Agent: curl/7.37.1 > Host: gnupg.org > Accept: */*
Any idea how to get the full certificate information form a command line tool (cURL or other)?
-
Admin over 7 years
-
Admin about 6 yearsProbably depends on the version too. My current
curl
with flag--verbose
shows the full server certificate content.
-
-
Adam Matan over 9 yearsThere seems to be an error with this command:
OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command.
-
Pedro Perez over 9 yearsHi Adam, it works on my Ubuntu and it should work on any Linux. By the looks of the error you posted I would say you might have mistyped the host or the port? gnupg.org:443 works for me, too. What do you get if you just run: echo | openssl s_client -showcerts -connect gnupg.org:443 2>/dev/null
-
Håkan Lindqvist over 9 yearsUnfortunately, very little of the certificate data is presented in human-readable format by that command.
-
Håkan Lindqvist over 9 years@AdamMatan Did you include the full command after the second pipe? The error message looks like the second openssl invocation ended up running in interactive mode (ie
openssl
vsopenssl x509 -inform pem -noout -text
). What Pedro wrote works fine for me. -
Adam Matan over 9 years@HåkanLindqvist Perfect, I probably just missed the suffix.
-
chutz over 8 yearsNote that while s_client will print the whole chain, the last piped command will only print information about the first certificate.
-
Valien almost 8 yearsTook this and put it in a simple bash script so you can query multiple domains without having to edit the command line all the time. github.com/Valien/Bash-alicious/blob/master/ssl-query.sh
-
Tilo over 7 yearshow to adapt it to print the details of the entire cert chain?
-
camdixon about 7 yearsI disagree with previous comment, this command tells me what I need to know and is very useful. +1 for answer.
-
camdixon about 7 yearsIf you specifically want to test for TLS 1.2 you can add -tls1_2
-
Per Lundberg about 7 yearsDoesn't work for me, doesn't include the start/expire dates.
-
Ross Presser almost 7 yearsSince some recent change in curl (somewhere between 49 and 52) this doesn't display anything at all about the certificate. :(
-
FooBee almost 7 yearsThis needs a lot more explanation.
-
Jeff over 6 yearsagree with need for explanation, but it does work for me, so +1
-
Noah Huppert over 6 yearsMade this into a script: github.com/Noah-Huppert/scripts/blob/master/sslinfo
-
mwfearnley over 6 yearsWhat is the
echo |
bit for? Is there a part of the command that expects user input? -
Pedro Perez over 6 yearsThe openssl command establishes a connection against the destination host. The
echo |
part sends empty data (not sure exactly what :P) that prompts a response from the server instead of just waiting for timeout. If you try without it you'll still get the desired results, but would get hung for a few seconds until the connection times out. -
hemp over 6 years
echo
by itself is equivalent toecho ''
.. it sends an empty string to stdout.cat /dev/null |
would work also and is a bit more self-explanatory. -
Jeshan almost 6 yearsremove the 2>&1
-
adriaan almost 6 yearsIf you would like to just know the expiry date, you can replace
-text
with-enddate
, check for other options (openssl x509 help
). -
dave_thompson_085 over 5 years(fixed) @hemp:
echo
by itself outputs one newline character, then exits which causes the pipe to return EOF to openssl, which is actually what causes openssl to complete. Redirecting with</dev/null
(or Windows<NUL:
but not on versions of OpenSSL before about 2016 which had a bug here) also works and is IMO even better. -
simon about 5 yearsbrilliant, much more useful default output than openssl (which needs decoding).
-
Dimitry K over 4 yearsI had a weird situation where i was using this script to request as shown
-servername smth.mydomain.com
but was receiving certificate for a different domain (hosted on the same server). First i thought that SSL was misconfigured on the server, but Chrome and Firefox correctly were seeing cert forsmth.mydomain.com
so my conclusion was that - this command doesn't really show the full picture, or there's more to SNI and servername than just specifying it there... (the curl solution from @AntonioFeitosa also shows that different domain). Seems like it shows whatever set as 'default cert'.. -
Dimitry K over 4 yearsThis seems to be the easiest way to check all domains supported by ssl-cert `keytool -printcert -sslserver smth.yourdomain.com | grep -E 'Owner|DNSName' this will show "default domain name" of the cert AND ALTERNATIVE DOMAIN NAMES of the cert
-
Dimitry K over 4 yearsThis also doesn't show Alternative Names which are on that cert.
-
Dimitry K over 4 yearsContinue: ok, i found the culprit. When looking at the shell command above, I decided that the last part of the pipe "decoding certs" wasn't necessary :O and thus in my output I only saw single CN name
default.mydomain.com
("default domain on the cert"). However in my case domain had multiple "Alternative names" likesmth.mydomain.com
,blog.mydomain.com
). Those names are only visible when you decode cert. I could also see them usingkeytool
method described below by @dave_thompson_085 . Hope this helps someone. -
Walter K over 4 yearsIf you need to see the cert's fingerprints then this command is far better than the
curl -v
suggestions in other answers. -
Ozymandias over 3 yearsThis is the only one in this thread showing the subject alternative names for the certificate.
-
Mike Andrews over 3 yearsOf all the other solutions (why is this basic operation so hard?), this is the least cumbersome. It's likely the one Trinity will prefer, too.
-
Håkan Lindqvist over 3 years@Trismegistos I don't believe that is a thing. You can certainly pipe the certificate in the output here into
openssl x509
(which does have a-text
option where it prints a human readable representation), like in serverfault.com/a/661982/183318 But if you want to improve this answer, you really shouldn't address me as I did not write it. -
entpnerd about 3 yearsThis answer worked great on my Mac for giving me details of a local certificate that I had for an app that I was trying to learn more about. I found the details of the certificate by using command
cat my-cert-file.pem | openssl x509 -inform pem -noout -text
. -
YCN- over 2 yearsThanks a lot ! simplest answer so far!
-
Justin Fortier over 2 yearsHonestly the most elegant and simplest of the answers here. Going to add this to my snippets. Thanks.
-
MSpreij about 2 years@entpnerd: openssl can read the file by itself using the
-in
argument, and-inform pem
is default. This is what I use:function cert () { openssl x509 -text -noout -in "$1" | less -F }
. Use like$ cert somefile.pem
($1 will be substituted for the filename). With an almost identical functioncsr
, replacing sub-commandx509
withreq
, you can view certificate signing requests. -
Admin about 2 yearsYour answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.