Wyświetlanie szczegółów zdalnego certyfikatu SSL za pomocą narzędzi CLI

187

W Chrome kliknięcie zielonej ikony blokady HTTPS otwiera okno ze szczegółami certyfikatu:

wprowadź opis zdjęcia tutaj

Kiedy spróbowałem tego samego z cURL, otrzymałem tylko niektóre informacje:

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

Masz pomysł, jak uzyskać pełne informacje o certyfikacie z narzędzia wiersza polecenia (cURL lub innego)?

Adam Matan
źródło
Prawdopodobnie zależy również od wersji. Mój bieżący curlz flagą --verbosepokazuje pełną treść certyfikatu serwera.
Patrick Mevzek,

Odpowiedzi:

263

Powinieneś być w stanie używać OpenSSL do swoich celów:

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

To polecenie łączy się z żądaną witryną i przesyła certyfikat w formacie PEM do innego polecenia openssl, które odczytuje i analizuje szczegóły.

(Należy pamiętać, że -servernameparametr „redundantny” jest konieczny, aby opensslwykonać żądanie z obsługą SNI.)

Pedro Perez
źródło
Wydaje się, że występuje błąd w tym poleceniu:OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command.
Adam Matan
2
@AdamMatan Czy załączyłeś pełne polecenie po drugim potoku? Komunikat o błędzie wygląda, jakby drugie wywołanie openssl zakończyło się uruchomieniem w trybie interaktywnym (tj. opensslVs openssl x509 -inform pem -noout -text). To, co napisał Pedro, działa dobrze dla mnie.
Håkan Lindqvist
4
Zauważ, że podczas gdy s_client wypisze cały łańcuch, ostatnie polecenie potokowe wypisze tylko informacje o pierwszym certyfikacie.
chutz
1
echosamo w sobie jest równoznaczne z echo ''... wysyła pusty ciąg na standardowe wyjście. cat /dev/null |działałoby również i jest nieco bardziej zrozumiałe.
konopie
2
Jeśli chcesz po prostu poznać datę ważności , można zastąpić -textz -enddate, sprawdź inne opcje ( openssl x509 help).
adriaan
63

Proste rozwiązanie

To mój codzienny skrypt:

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

Wynik:

* 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
źródło
5
Nie działa dla mnie, nie zawiera dat rozpoczęcia / wygaśnięcia.
Per Lundberg
4
Od czasu niedawnej zmiany zawijania (gdzieś pomiędzy 49 a 52) nie wyświetla to wcale certyfikatu. :(
Ross Presser
usuń 2> i 1
Jeshan Babooa
27

Zależy, jakiego rodzaju informacji chcesz, ale:

openssl s_client -showcerts -connect gnupg.org:443

powinien dać ci najwięcej, choć nie tak ładnie czytelny dla ludzi jak Chrome.

oszust
źródło
1
Niestety, bardzo mało danych certyfikatu jest prezentowanych w formacie czytelnym dla człowieka.
Håkan Lindqvist
9
Nie zgadzam się z poprzednim komentarzem, to polecenie mówi mi, co muszę wiedzieć i jest bardzo przydatne. +1 za odpowiedź.
camdixon
Jeśli chcesz przetestować TLS 1.2, możesz dodać -tls1_2
camdixon
23
nmap -p 443 --script ssl-cert gnupg.org

W -p 443Określa skanowanie portu 443 tylko. Wszystkie porty zostaną przeskanowane, jeśli zostaną pominięte, i zostaną wyświetlone szczegóły certyfikatu dla każdej znalezionej usługi SSL. --script ssl-certOpowiada skryptowego silnika Nmap , aby uruchomić tylko ssl-certskrypt. Z dokumentu ten skrypt „(r) pobiera certyfikat SSL serwera. Ilość informacji drukowanych na temat certyfikatu zależy od poziomu szczegółowości”.

Przykładowe dane wyjściowe:

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
źródło
6

Aby sprawdzić szczegóły certyfikatu SSL, używam następującego narzędzia wiersza poleceń, odkąd jest ono dostępne:

https://github.com/azet/tls_tools

Dobrze jest dwukrotnie sprawdzić, czy wszystkie informacje są prawidłowe do ponownego wystawiania certyfikatów lub sprawdzania poprawności istniejących, a także jako niewielką zależność ORAZ nie wymaga konfiguracji.

Oto jak wygląda kilka pierwszych wierszy wyniku:

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

Po tych wynikach następuje cały łańcuch certyfikatów na tym samym poziomie szczegółowości.

To, co lubię, zamiast być narzędziem cli zorientowanym na ssl, takim jak s_client openssl, to ono próbuje po prostu wykonać jedną pracę, której potrzebujemy przez większość czasu. Oczywiście openssl jest bardziej elastyczny (tzn. Również sprawdza klientcert, imapy na nieparzystych portach itp.) - ale nie zawsze tego potrzebuję.

Alternatywnie, jeśli masz czas na kopanie i konfigurowanie lub doceniasz więcej funkcji, istnieje większe narzędzie o nazwie sslyze (nie używa go od zależności i instalacji ...)

Florian Heigl
źródło
5

Dla kompletności: jeśli masz zainstalowany system Java 7 lub nowszy

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

pokazuje łańcuch (jak podano ) z prawie wszystkimi szczegółami w przeważnie raczej brzydkim formacie.

Czy powinieneś mieć zainstalowaną Javę w swoim systemie, nie odpowiadam.

dave_thompson_085
źródło
genialne, znacznie bardziej przydatne domyślne wyjście niż openssl (który wymaga dekodowania).
simon
4

Używam do tego skryptu powłoki. To tylko opakowanie wokół polecenia openssl, które ratuje mnie przed zapamiętaniem składni.

Zapewnia opcje analizowania większości informacji o certyfikacie, którymi zwykle jestem zainteresowany, lub wyświetlania surowego wyniku opensl.

Może wysłać zapytanie do lokalnego pliku certyfikatu lub zdalnego serwera.

Stosowanie:

$ 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

Możesz pobrać skrypt tutaj: http://giantdorks.org/alain/shell-script-to-check-ssl-certificate-info-like-expiration-date-and-subject/

Alain Kelder
źródło
Link jest martwy.
Adam Matan
4

Jeśli chcesz to zrobić w systemie Windows, możesz użyć programu PowerShell z następującą funkcją:

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
}

To pozwala ci robić porządne rzeczy, takie jak

#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
źródło
2
nmap -sV -sC google.com -p 443
Sergio Rua
źródło
3
To wymaga znacznie więcej wyjaśnień.
Sven
zgadzam się z potrzebą wyjaśnienia, ale to działa dla mnie, więc +1
Jeff
2

Jeśli potrzebujesz tylko daty wygaśnięcia (która nie jest dokładnie odpowiedzią, ale 9/10, dla których ludzie używają danych certyfikatu Chrome), możesz użyć:

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

Przydatny do skryptów itp.

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
źródło