¿Cómo verificar la huella digital SSL por línea de comando? (wget, rizo, ...)

5

Usando un descargador de sitios web de línea de comandos, como wget , curl o cualquier otro ... En un script ...

Tengo el SHA-1 y el certificado de huella digital SHA-256 de un sitio web. Debido a problemas de seguridad ( 1 ) ( 2 ), no quiero usar el sistema público de certificación SSL. La huella dactilar debe estar codificada.

¿Puede una aplicación similar a wget verificar la huella digital de SSL?

wget no tiene tal funcionalidad. ( 3 )

Al usar wget --ca-certificate o curl --cacert tendría que ejecutar mi propia autoridad de certificación local, lo que me gustaría evitar, porque eso agrega mucha complejidad. También es ultra difícil y nadie lo había hecho nunca antes. ( 4 )

¿No hay ninguna herramienta, como
download --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz https://site.com ?

Por supuesto, la solución no debe ser vulnerable a TOCTOU. ( 5 ) El MITM podría devolver una huella digital válida para la solicitud de cliente de openssl y manipular la siguiente solicitud de configuración.

    
pregunta James Mitch 19.09.2012 - 22:51
fuente

1 respuesta

7

NUEVA RESPUESTA:

Al revisar su enlace # 4, parece que ha investigado las utilidades existentes y ha recibido la respuesta de que lo que desea debería programarse. Hacerlo es relativamente trivial. El siguiente script de Perl hará lo que quieras:

#!/usr/bin/perl
# Code snippets taken from Net::SSLeay documentation and mildly modified.
# Requires a newer version of SSLeay (tested with 1.48)
# Needless to say, verify correct $host and $fingerprint before testing!!!

use Net::SSLeay qw(get_https3);

$host = "www.google.com";
$port = 443;
$fingerprint = "C1:95:6D:C8:A7:DF:B2:A5:A5:69:34:DA:09:77:8E:3A:11:02:33:58";

($p, $resp, $hdrs, $server_cert) = get_https3($host, $port, '/');
if (!defined($server_cert) || ($server_cert == 0)) {
    warn "Subject Name: undefined, Issuer  Name: undefined";
} elsif (Net::SSLeay::X509_get_fingerprint($server_cert, "sha1") ne $fingerprint) {
    warn 'Invalid certificate fingerprint '
        .  Net::SSLeay::X509_get_fingerprint($server_cert, "sha1")
        . ' for ' . Net::SSLeay::X509_NAME_oneline(
             Net::SSLeay::X509_get_subject_name($server_cert));
} else {
    print $p;
}

Como se describe en la documentación de Net :: SSLeay, este método significa verificación después de la transacción HTTP , por lo que no debe usarse si desea verificar que está hablando con el servidor correcto < em> antes enviándoles datos. Pero si todo lo que estás haciendo es decidir si confiar o no en lo que acabas de descargar (lo que parece que eres de tu referencia # 4), está bien.

ANTIGUA RESPUESTA:

Puede usar openssl como se describe aquí :

A ingenio,

openssl s_client -connect <host>:<port> < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin

(La respuesta anterior era) Actualizada

Como señaló @Gilles, esto no cumple con el requisito de combinar la verificación del certificado con la recuperación de contenido real.

Debido a que openssl s_client combina la información del certificado y la respuesta del servidor en la secuencia stdout, no se puede utilizar simplemente para este propósito. Probablemente sea posible escribir un script que absorba la salida combinada y separe los dos según un análisis de prueba simple, pero esa no es exactamente una solución llave en mano.

    
respondido por el gowenfawr 19.09.2012 - 23:14
fuente

Lea otras preguntas en las etiquetas