Displaying a remote SSL certificate details using CLI tools

595,479

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.

Share:
595,479

Related videos on Youtube

Adam Matan
Author by

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&amp;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, 2022

Comments

  • Adam Matan
    Adam Matan over 1 year

    In Chrome, clicking on the green HTTPS lock icon opens a window with the certificate details:

    enter image description here

    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
      Admin over 7 years
    • Admin
      Admin about 6 years
      Probably depends on the version too. My current curl with flag --verbose shows the full server certificate content.
  • Adam Matan
    Adam Matan over 9 years
    There seems to be an error with this command: OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command.
  • Pedro Perez
    Pedro Perez over 9 years
    Hi 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
    Håkan Lindqvist over 9 years
    Unfortunately, very little of the certificate data is presented in human-readable format by that command.
  • Håkan Lindqvist
    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 vs openssl x509 -inform pem -noout -text). What Pedro wrote works fine for me.
  • Adam Matan
    Adam Matan over 9 years
    @HåkanLindqvist Perfect, I probably just missed the suffix.
  • chutz
    chutz over 8 years
    Note that while s_client will print the whole chain, the last piped command will only print information about the first certificate.
  • Valien
    Valien almost 8 years
    Took 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
    Tilo over 7 years
    how to adapt it to print the details of the entire cert chain?
  • camdixon
    camdixon about 7 years
    I disagree with previous comment, this command tells me what I need to know and is very useful. +1 for answer.
  • camdixon
    camdixon about 7 years
    If you specifically want to test for TLS 1.2 you can add -tls1_2
  • Per Lundberg
    Per Lundberg about 7 years
    Doesn't work for me, doesn't include the start/expire dates.
  • Ross Presser
    Ross Presser almost 7 years
    Since some recent change in curl (somewhere between 49 and 52) this doesn't display anything at all about the certificate. :(
  • FooBee
    FooBee almost 7 years
    This needs a lot more explanation.
  • Jeff
    Jeff over 6 years
    agree with need for explanation, but it does work for me, so +1
  • Noah Huppert
    Noah Huppert over 6 years
  • mwfearnley
    mwfearnley over 6 years
    What is the echo | bit for? Is there a part of the command that expects user input?
  • Pedro Perez
    Pedro Perez over 6 years
    The 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
    hemp over 6 years
    echo by itself is equivalent to echo '' .. it sends an empty string to stdout. cat /dev/null | would work also and is a bit more self-explanatory.
  • Jeshan
    Jeshan almost 6 years
    remove the 2>&1
  • adriaan
    adriaan almost 6 years
    If 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
    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
    simon about 5 years
    brilliant, much more useful default output than openssl (which needs decoding).
  • Dimitry K
    Dimitry K over 4 years
    I 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 for smth.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
    Dimitry K over 4 years
    This 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
    Dimitry K over 4 years
    This also doesn't show Alternative Names which are on that cert.
  • Dimitry K
    Dimitry K over 4 years
    Continue: 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" like smth.mydomain.com, blog.mydomain.com). Those names are only visible when you decode cert. I could also see them using keytool method described below by @dave_thompson_085 . Hope this helps someone.
  • Walter K
    Walter K over 4 years
    If you need to see the cert's fingerprints then this command is far better than the curl -v suggestions in other answers.
  • Ozymandias
    Ozymandias over 3 years
    This is the only one in this thread showing the subject alternative names for the certificate.
  • Mike Andrews
    Mike Andrews over 3 years
    Of 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
    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
    entpnerd about 3 years
    This 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-
    YCN- over 2 years
    Thanks a lot ! simplest answer so far!
  • Justin Fortier
    Justin Fortier over 2 years
    Honestly the most elegant and simplest of the answers here. Going to add this to my snippets. Thanks.
  • MSpreij
    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 function csr, replacing sub-command x509 with req, you can view certificate signing requests.
  • Admin
    Admin about 2 years
    Your 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.