Anzeigen von Details zu einem Remote-SSL-Zertifikat mithilfe von CLI-Tools

187

Wenn Sie in Chrome auf das grüne HTTPS-Schlosssymbol klicken, wird ein Fenster mit den Zertifikatdetails geöffnet:

Bildbeschreibung hier eingeben

Als ich dasselbe mit cURL versuchte, bekam ich nur einige Informationen:

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

Haben Sie eine Idee, wie Sie die vollständigen Zertifikatinformationen aus einem Befehlszeilentool (cURL oder einem anderen) abrufen können?

Adam Matan
quelle
Kommt wohl auch auf die Version an. Mein aktuelles curlFlag mit --verbosezeigt den vollständigen Inhalt des Serverzertifikats an.
Patrick Mevzek

Antworten:

263

Sie sollten in der Lage sein, OpenSSL für Ihre Zwecke zu verwenden:

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

Dieser Befehl stellt eine Verbindung zur gewünschten Website her und leitet das Zertifikat im PEM-Format an einen anderen openssl-Befehl weiter, der die Details liest und analysiert.

(Beachten Sie, dass der -servernameParameter "redundant" erforderlich ist, um openssleine Anfrage mit SNI-Unterstützung zu stellen.)

Pedro Perez
quelle
Bei diesem Befehl ist anscheinend ein Fehler aufgetreten:OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command.
Adam Matan
2
@AdamMatan Haben Sie den vollständigen Befehl nach der zweiten Pipe eingefügt? Die Fehlermeldung sieht so aus, als ob der zweite openssl-Aufruf im interaktiven Modus (dh opensslvs openssl x509 -inform pem -noout -text) ausgeführt wurde. Was Pedro schrieb, funktioniert gut für mich.
Håkan Lindqvist
4
Beachten Sie, dass während s_client die gesamte Kette ausgibt, der letzte über Pipe übermittelte Befehl nur Informationen zum ersten Zertifikat ausgibt.
Chutz
1
echoan sich ist äquivalent zu echo ''.. es sendet eine leere Zeichenfolge an stdout. cat /dev/null |würde auch funktionieren und ist etwas selbsterklärender.
Hanf
2
Wenn Sie möchten , nur das wissen , Ablaufdatum , können Sie ersetzen -textmit -enddate, überprüfen Sie für andere Optionen ( openssl x509 help).
Adriaan
63

Einfache lösung

Das ist mein alltägliches Drehbuch:

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

Ausgabe:

* 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
quelle
5
Funktioniert bei mir nicht, enthält keine Start- / Ablaufdaten.
Per Lundberg
4
Seit einigen kürzlichen Änderungen der Wellung (irgendwo zwischen 49 und 52) zeigt dies überhaupt nichts über das Zertifikat an. :(
Ross Presser
Entfernen Sie die 2> & 1
Jeshan Babooa
27

Hängt davon ab, welche Art von Informationen Sie benötigen, aber:

openssl s_client -showcerts -connect gnupg.org:443

sollten Sie am meisten geben, obwohl nicht so gut lesbar wie Chrome präsentiert.

Schwindler
quelle
1
Leider werden durch diesen Befehl nur sehr wenige Zertifikatdaten in einem für Menschen lesbaren Format dargestellt.
Håkan Lindqvist
9
Ich bin mit dem vorherigen Kommentar nicht einverstanden. Dieser Befehl sagt mir, was ich wissen muss und ist sehr nützlich. +1 zur Beantwortung.
Camdixon
Wenn Sie speziell auf TLS 1.2 testen möchten, können Sie -tls1_2
camdixon
23
nmap -p 443 --script ssl-cert gnupg.org

Das -p 443gibt an, nur Port 443 zu scannen. Alle Ports werden gescannt, wenn sie weggelassen werden, und die Zertifikatdetails für jeden gefundenen SSL-Dienst werden angezeigt. Das --script ssl-certweist das Nmap-ssl-cert Skriptmodul an, nur das Skript auszuführen . Über das Dokument wird mit diesem Skript "(R) das SSL-Zertifikat eines Servers abgerufen. Die Menge der über das Zertifikat gedruckten Informationen hängt von der Ausführlichkeitsstufe ab."

Beispielausgabe:

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
quelle
6

Um nach SSL-Zertifikatdetails zu suchen, verwende ich das folgende Befehlszeilentool, seitdem es verfügbar ist:

https://github.com/azet/tls_tools

Es ist toll zu doppelt überprüfen Sie alle Informationen für Neuausstellung certs oder Validierung bestehender richtig haben, und auch so wenig Abhängigkeiten und es erfordert keine Einrichtung.

So sehen die ersten Zeilen der Ausgabe aus:

$ ./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 

Dieser Ausgabe folgt die gesamte Zertifikatskette auf derselben Detailebene.

Was mir gefällt, anstatt ein ssl-zentriertes Cli-Tool wie openssls s_client zu sein, versucht dieses Tool nur den einen Job zu erledigen, den wir die meiste Zeit brauchen. Natürlich ist openssl flexibler (dh überprüft auch Client-Zertifikate, Imaps auf ungeraden Ports usw.) - aber das brauche ich nicht immer.

Alternativ, wenn Sie Zeit haben, sich in & setup zu vertiefen oder mehr Funktionen zu schätzen, gibt es das größere Tool mit dem Namen sslyze (es wird seit Abhängigkeiten und Installation nicht mehr verwendet ...)

Florian Heigl
quelle
5

Der Vollständigkeit halber: Wenn Sie Java 7 oder höher auf Ihrem System installiert haben

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

zeigt die Kette (wie bedient) mit fast allen Details in einem meist eher hässlichen Format.

Ob Sie Java auf Ihrem System installiert haben sollten, antworte ich nicht.

dave_thompson_085
quelle
brillante, viel nützlichere Standardausgabe als openssl (das dekodiert werden muss).
Simon
4

Ich benutze dafür ein Shell-Skript. Es ist nur ein Wrapper um den Befehl openssl, der mich davor bewahrt, mich an die Syntax zu erinnern.

Es bietet Optionen zum Parsen der meisten Zertifikatsinformationen, an denen ich normalerweise interessiert bin, oder zum Anzeigen der unformatierten OpenSSL-Ausgabe.

Kann entweder eine lokale Zertifikatsdatei oder einen Remote-Server abfragen.

Verwendungszweck:

$ 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

Sie können das Skript hier herunterladen : http://giantdorks.org/alain/shell-script-to-check-ssl-certificate-info-like-expiration-date-and-subject/

Alain Kelder
quelle
Der Link ist tot.
Adam Matan
4

Wenn Sie dies unter Windows tun möchten, können Sie PowerShell mit der folgenden Funktion verwenden:

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
}

Dies ermöglicht es Ihnen, einige nette Dinge wie zu tun

#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*
Neossian
quelle
2
nmap -sV -sC google.com -p 443
Sergio Rua
quelle
3
Das bedarf noch viel mehr Erklärung.
Sven
Ich stimme dem Bedürfnis nach Erklärung zu, aber es funktioniert für mich, also +1
Jeff
2

Wenn Sie nur das Ablaufdatum haben möchten (was nicht genau die Antwort ist, sondern 9/10, wofür die Nutzer die Chrome-Zertifizierungsdetails verwenden), können Sie Folgendes verwenden:

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

Nützlich für Skripte 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
c4urself
quelle