Visualización de detalles de un certificado SSL remoto utilizando herramientas CLI


187

En Chrome, al hacer clic en el ícono verde de bloqueo HTTPS se abre una ventana con los detalles del certificado:

ingrese la descripción de la imagen aquí

Cuando intenté lo mismo con cURL, obtuve solo parte de la información:

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

¿Alguna idea de cómo obtener la información completa del certificado de una herramienta de línea de comandos (cURL u otra)?



Probablemente depende de la versión también. Mi marca actual curlcon --verbosemuestra el contenido completo del certificado del servidor.
Patrick Mevzek

Respuestas:


264

Debería poder usar OpenSSL para su propósito:

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

Ese comando se conecta al sitio web deseado y canaliza el certificado en formato PEM a otro comando openssl que lee y analiza los detalles.

(Tenga en cuenta que el -servernameparámetro "redundante" es necesario para hacer openssluna solicitud con soporte SNI).


Parece haber un error con este comando:OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command.
Adam Matan

2
@AdamMatan ¿Incluyó el comando completo después de la segunda tubería? El mensaje de error parece que la segunda invocación de openssl terminó ejecutándose en modo interactivo (es decir, opensslvs openssl x509 -inform pem -noout -text). Lo que Pedro escribió funciona bien para mí.
Håkan Lindqvist

44
Tenga en cuenta que si bien s_client imprimirá toda la cadena, el último comando canalizado solo imprimirá información sobre el primer certificado.
chutz

1
echopor sí mismo es equivalente a echo ''... envía una cadena vacía a stdout. cat /dev/null |funcionaría también y es un poco más autoexplicativo.
cáñamo

2
Si desea conocer la fecha de caducidad , puede reemplazar -textpor -enddate, verifique otras opciones ( openssl x509 help).
adriaan

63

Solución simple

Ese es mi guión cotidiano:

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

Salida:

* 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

55
No funciona para mí, no incluye las fechas de inicio / caducidad.
Por Lundberg

44
Debido a algunos cambios recientes en el rizo (entre 49 y 52), esto no muestra nada en absoluto sobre el certificado. :(
Ross Presser

eliminar el 2> y 1
Jeshan Babooa

27

Depende del tipo de información que desee, pero:

openssl s_client -showcerts -connect gnupg.org:443

debería darte más, aunque no tan agradablemente legible para los humanos como Chrome lo presenta.


1
Desafortunadamente, ese comando presenta muy pocos datos del certificado en formato legible para humanos.
Håkan Lindqvist

99
No estoy de acuerdo con el comentario anterior, este comando me dice lo que necesito saber y es muy útil. +1 por respuesta.
camdixon

Si desea probar específicamente TLS 1.2, puede agregar -tls1_2
camdixon

23
nmap -p 443 --script ssl-cert gnupg.org

Las -p 443especifica para escanear el puerto 443 solamente. Se omitirán todos los puertos si se omite, y se mostrarán los detalles del certificado de cualquier servicio SSL que se encuentre. El --script ssl-certle dice al motor de secuencias de comandos Nmap que ejecute solo la ssl-certsecuencia de comandos. Desde el documento, este script "(r) evoca el certificado SSL de un servidor. La cantidad de información impresa sobre el certificado depende del nivel de detalle".

Salida de muestra:

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

6

Para verificar los detalles del certificado SSL, uso la siguiente herramienta de línea de comandos desde que está disponible:

https://github.com/azet/tls_tools

Es bueno verificar que tenga toda la información correcta para volver a emitir certificados o validar los existentes, y también como pocas dependencias Y no requiere configuración.

Así se ven las primeras líneas de la salida:

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

A esa salida le sigue toda la cadena de certificados con el mismo nivel de detalle.

Lo que me gusta es que en lugar de ser una herramienta cli centrada en SSL como el cliente_s de openssl, esta intenta hacer el trabajo que necesitamos la mayor parte del tiempo. Por supuesto, openssl es más flexible (es decir, también verifica los certificados de clientes, imágenes en puertos impares, etc.), pero no siempre necesito eso.

Alternativamente, si tiene tiempo para profundizar y configurar o apreciar más funciones, existe la herramienta más grande llamada sslyze (no la usa desde dependencias e instalación ...)


5

Para completar: si ha instalado en su sistema Java 7 o superior

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

muestra la cadena (como se sirve) con casi todos los detalles en un formato bastante feo.

Si debería tener Java instalado en su sistema, no respondo.


salida predeterminada brillante, mucho más útil que openssl (que necesita decodificación).
Simon

4

Yo uso un script de shell para esto. Es solo un contenedor alrededor del comando openssl que me salva de recordar la sintaxis.

Proporciona opciones para analizar la mayor parte de la información del certificado que normalmente me interesa o para mostrar la salida de openssl sin formato.

Puede consultar un archivo de certificado local o un servidor remoto.

Uso:

$ 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

Puede obtener el script aquí: http://giantdorks.org/alain/shell-script-to-check-ssl-certificate-info-like-expiration-date-and-subject/


El enlace está muerto.
Adam Matan

4

Si desea hacer esto en Windows, puede usar PowerShell con la siguiente función:

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
}

Esto le permite hacer algunas cosas interesantes como

#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*

2
nmap -sV -sC google.com -p 443

3
Esto necesita mucha más explicación.
Sven

de acuerdo con la necesidad de explicación, pero funciona para mí, así que +1
Jeff el

2

Si solo desea la fecha de vencimiento (que no es exactamente la respuesta, pero es 9/10 para lo que las personas usan los detalles del certificado de Chrome), puede usar:

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

Útil para guiones, 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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.