Affichage des détails d'un certificat SSL distant à l'aide d'outils CLI

187

Sous Chrome, un clic sur l'icône de verrou HTTPS vert ouvre une fenêtre contenant les détails du certificat:

entrez la description de l'image ici

Quand j'ai essayé la même chose avec cURL, je n'ai eu que quelques informations:

$ 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: */*

Une idée de comment obtenir les informations complètes du certificat à partir d’un outil de ligne de commande (cURL ou autre)?

Adam Matan
la source
Cela dépend probablement aussi de la version. Mon curlindicateur actuel avec --verboseindique le contenu complet du certificat de serveur.
Patrick Mevzek

Réponses:

264

Vous devriez pouvoir utiliser OpenSSL pour vos besoins:

echo | openssl s_client -showcerts -servername gnupg.org -connect gnupg.org:443 2>/dev/null | openssl x509 -inform pem -noout -text

Cette commande se connecte au site Web souhaité et dirige le certificat au format PEM vers une autre commande openssl qui lit et analyse les détails.

(Notez que le -servernameparamètre "redondant" est nécessaire pour effectuer opensslune demande avec le support SNI.)

Pedro Perez
la source
Il semble y avoir une erreur avec cette commande:OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command.
Adam Matan le
2
@AdamMatan Avez-vous inclus la commande complète après le deuxième canal? Le message d'erreur ressemble à la seconde invocation openssl qui s'exécutait en mode interactif (c.-à-d. opensslVs openssl x509 -inform pem -noout -text). Ce que Pedro a écrit fonctionne bien pour moi.
Håkan Lindqvist le
4
Notez que si s_client imprimera toute la chaîne, la dernière commande diffusée n’imprimera que les informations relatives au premier certificat.
Chutz
1
echoen soi équivaut à echo ''.. il envoie une chaîne vide à stdout. cat /dev/null |fonctionnerait aussi et est un peu plus explicite.
chanvre
2
Si vous souhaitez simplement connaître la date d'expiration , vous pouvez remplacer -textpar -enddate, recherchez d'autres options ( openssl x509 help).
adriaan
63

Solution simple

C'est mon script de tous les jours:

curl --insecure -v https://www.google.com 2>&1 | awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }'

Sortie:

* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
*    server certificate verification SKIPPED
*    server certificate status verification SKIPPED
*    common name: www.google.com (matched)
*    server certificate expiration date OK
*    server certificate activation date OK
*    certificate public key: RSA
*    certificate version: #3
*    subject: C=US,ST=California,L=Mountain View,O=Google Inc,CN=www.google.com
*    start date: Wed, 24 May 2017 17:39:15 GMT
*    expire date: Wed, 16 Aug 2017 17:13:00 GMT
*    issuer: C=US,O=Google Inc,CN=Google Internet Authority G2
*    compression: NULL
* ALPN, server accepted to use http/1.1
* Connection #0 to host www.google.com left intact
Antonio Feitosa
la source
5
Cela ne fonctionne pas pour moi, n'inclut pas les dates de début / expiration.
Par Lundberg
4
Depuis quelques changements récents dans la boucle (entre 49 et 52), cela n’affiche rien du tout sur le certificat. :(
Ross Presser
enlever les 2> & 1
Jeshan Babooa
27

Cela dépend du type d’information que vous souhaitez, mais:

openssl s_client -showcerts -connect gnupg.org:443

devrait vous en donner le plus, mais pas aussi lisiblement que le présente Chrome.

faux
la source
1
Malheureusement, très peu de données de certificat sont présentées dans un format lisible par l'homme par cette commande.
Håkan Lindqvist
9
Je ne suis pas d'accord avec le commentaire précédent, cette commande me dit ce que j'ai besoin de savoir et est très utile. +1 pour la réponse.
camdixon
Si vous souhaitez spécifiquement tester TLS 1.2, vous pouvez ajouter -tls1_2
camdixon
23
nmap -p 443 --script ssl-cert gnupg.org

Le -p 443spécifie pour analyser le port 443 uniquement. Tous les ports seront analysés s'il est omis et les détails du certificat pour tout service SSL trouvé seront affichés. Le --script ssl-certindique au moteur de script Nmap d'exécuter uniquement le ssl-certscript. A partir de la doc, ce script "récupère le certificat SSL d'un serveur. La quantité d'informations imprimées sur le certificat dépend du niveau de verbosité."

Exemple de sortie:

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
Jose Quinteiro
la source
6

Pour vérifier les détails du certificat SSL, j'utilise l'outil de ligne de commande suivant depuis qu'il est disponible:

https://github.com/azet/tls_tools

Il est bon de vérifier que toutes les informations sont correctes pour la réémission de certificats ou la validation de certificats existants, ainsi que le nombre de dépendances ET qu'il ne nécessite aucune configuration.

Voici à quoi ressemblent les premières lignes de la sortie:

$ ./check_certificate_chain.py gnupg.org 443

>> Certificate Chain:

 [+]*       OU=Domain Control Validated, OU=Gandi Standard SSL, CN=gnupg.org
 [+]**      C=FR, O=GANDI SAS, CN=Gandi Standard SSL CA
 [+]***     C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware

>> Certificate Information:

................................................................................
- [Subject]:        OU=Domain Control Validated, OU=Gandi Standard SSL, CN=gnupg.org
- [Issuer]:     C=FR, O=GANDI SAS, CN=Gandi Standard SSL CA
- [Valid from]:     Mar 18 00:00:00 2014 GMT
- [Valid until]:    Mar 18 23:59:59 2016 GMT
- [Authority]:      Is not a CA
- [Version]:        2
- [Serial No.]:     43845251655098616578492338727643475746
- [X.509 Extension Details]:
  -- [x509_authorityKeyIdentifier]:
       keyid:B6:A8:FF:A2:A8:2F:D0:A6:CD:4B:B1:68:F3:E7:50:10:31:A7:79:21 

Cette sortie est suivie par toute la chaîne de certificats au même niveau de détail.

Ce que j’aime, au lieu d’être un outil cli centré sur le ssl, comme le client s_client d’openssl, c’est celui-ci qui tente de faire le travail dont nous avons le plus souvent besoin. Bien sûr, openssl est plus flexible (c'est-à-dire qu'il permet également de vérifier les concerts, d'insérer des ports impairs, etc.), mais je n'en ai pas toujours besoin.

Alternativement, si vous avez le temps de creuser et d'installer ou d'apprécier plus de fonctionnalités, il y a le plus gros outil appelé sslyze (ne l'utilisant pas depuis les dépendances et installer ...)

Florian Heigl
la source
5

Pour être complet: si vous avez installé sur votre système Java 7 ou supérieur

 keytool -printcert -sslserver $host[:$port]

montre la chaîne (telle que servie) avec presque tous les détails dans un format plutôt plutôt moche.

Que vous devriez avoir Java installé sur votre système , je ne réponds pas.

dave_thompson_085
la source
Une sortie par défaut brillante et bien plus utile que openssl (qui nécessite un décodage).
simon
4

J'utilise un script shell pour cela. C'est juste un wrapper autour de la commande openssl qui m'empêche de me souvenir de la syntaxe.

Il fournit des options pour analyser la plupart des informations de certificat qui m'intéressent généralement, ou pour afficher une sortie openssl brute.

Peut interroger un fichier de certificat local ou un serveur distant.

Usage:

$ ssl-cert-info --help
Usage: ssl-cert-info [options]

This shell script is a simple wrapper around the openssl binary. It uses
s_client to get certificate information from remote hosts, or x509 for local
certificate files. It can parse out some of the openssl output or just dump all
of it as text.

Options:

  --all-info   Print all output, including boring things like Modulus and 
               Exponent.

  --alt        Print Subject Alternative Names. These will be typically be 
               additional hostnames that the certificate is valid for.

  --cn         Print commonName from Subject. This is typically the host for 
               which the certificate was issued.

  --debug      Print additional info that might be helpful when debugging this
               script.

  --end        Print certificate expiration date. For additional functionality
               related to certificate expiration, take a look at this script:
               "http://prefetch.net/code/ssl-cert-check".

  --dates      Print start and end dates of when the certificate is valid.

  --file       Use a local certificate file for input.

  --help       Print this help message.

  --host       Fetch the certificate from this remote host.

  --issuer     Print the certificate issuer.

  --most-info  Print almost everything. Skip boring things like Modulus and
               Exponent.

  --option     Pass any openssl option through to openssl to get its raw
               output.

  --port       Use this port when conneting to remote host. If ommitted, port
               defaults to 443.

  --subject    Print the certificate Subject -- typically address and org name.

Examples:

  1. Print a list of all hostnames that the certificate used by amazon.com 
     is valid for.

     ssl-cert-info --host amazon.com --alt
     DNS:uedata.amazon.com
     DNS:amazon.com
     DNS:amzn.com
     DNS:www.amzn.com
     DNS:www.amazon.com

  2. Print issuer of certificate used by smtp.gmail.com. Fetch certficate info
     over port 465.

     ssl-cert-info --host smtp.gmail.com --port 465 --issuer
     issuer= 
         countryName               = US
         organizationName          = Google Inc
         commonName                = Google Internet Authority G2

  3. Print valid dates for the certificate, using a local file as the source of 
     certificate data. Dates are formatted using the date command and display
     time in your local timezone instead of GMT.

     ssl-cert-info --file /path/to/file.crt --dates
     valid from: 2014-02-04 16:00:00 PST
     valid till: 2017-02-04 15:59:59 PST


  4. Print certificate serial number. This script doesn't have a special option
     to parse out the serial number, so will use the generic --option flag to
     pass '-serial' through to openssl.

     ssl-cert-info --host gmail.com --option -serial
     serial=4BF004B4DDC9C2F8

Vous pouvez obtenir le script ici: http://giantdorks.org/alain/shell-script-to-check-ssl-certificate-info-like-expiration-date-and-subject/

Alain Kelder
la source
Le lien est mort.
Adam Matan
4

Si vous voulez faire cela dans Windows, vous pouvez utiliser PowerShell avec la fonction suivante:

function Retrieve-ServerCertFromSocket ($hostname, $port=443, $SNIHeader, [switch]$FailWithoutTrust)
{
    if (!$SNIHeader) {
        $SNIHeader = $hostname
    }

    $cert = $null
    try {
        $tcpclient = new-object System.Net.Sockets.tcpclient
        $tcpclient.Connect($hostname,$port)

        #Authenticate with SSL
        if (!$FailWithoutTrust) {
            $sslstream = new-object System.Net.Security.SslStream -ArgumentList $tcpclient.GetStream(),$false, {$true}
        } else {
            $sslstream = new-object System.Net.Security.SslStream -ArgumentList $tcpclient.GetStream(),$false
        }

        $sslstream.AuthenticateAsClient($SNIHeader)
        $cert =  [System.Security.Cryptography.X509Certificates.X509Certificate2]($sslstream.remotecertificate)

     } catch {
        throw "Failed to retrieve remote certificate from $hostname`:$port because $_"
     } finally {
        #cleanup
        if ($sslStream) {$sslstream.close()}
        if ($tcpclient) {$tcpclient.close()}        
     }    
    return $cert
}

Cela vous permet de faire des choses intéressantes comme

#Save to file and open 
Retrieve-ServerCertFromSocket www.wrish.com 443 | Export-Certificate -FilePath C:\temp\test.cer ; start c:\temp\test.cer

#Display the cert details
Retrieve-ServerCertFromSocket www.wrish.com 443 | fl subject,*not*,Thumb*,ser*
Néossien
la source
2
nmap -sV -sC google.com -p 443
Sergio Rua
la source
3
Cela nécessite beaucoup plus d'explications.
Sven
d'accord avec le besoin d'explication, mais cela fonctionne pour moi, alors +1
Jeff
2

Si vous souhaitez uniquement connaître la date d'expiration (ce qui n'est pas exactement la réponse mais correspond au 9/10 pour lequel les utilisateurs utilisent les détails du certificat Chrome), vous pouvez utiliser:

echo | openssl s_client -connect google.com:443 2>/dev/null | openssl x509 -noout -enddate

Utile pour les scripts, etc.

c4urself@eos ~ → which ssl_expiry
ssl_expiry () {
  echo | openssl s_client -connect ${1}:443 2> /dev/null | openssl x509 -noout -enddate
}
c4urself@eos ~ → ssl_expiry google.com
notAfter=Jun 12 16:54:00 2018 GMT
nous-même
la source