Como verificar a impressão digital SSL por linha de comando? (wget, curl,…)

26

Usando um downloader de site de linha de comando, como wget , curl ou qualquer outro ... Em um script ...

Tenho a impressão digital certificada do SHA-1 e do SHA-256 de um site. Devido a preocupações de segurança ( 1 ) ( 2 ), eu não quero usar o sistema de autoridade de certificação SSL público. A impressão digital deve ser codificada.

Um aplicativo como o wget pode verificar a impressão digital SSL?

wget não tem essa funcionalidade. ( 3 )

Usando wget --ca-certificate ou curl --cacert , precisaria executar minha própria autoridade de certificação local, o que eu gostaria de evitar, porque isso adiciona muita complexidade. Também é ultra difícil e ninguém fez isso antes. ( 4 )

Não há nenhuma ferramenta, como download --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz https://site.com ?

A solução obviamente não deve ser vulnerável ao TOCTOU. ( 5 ) O MITM poderia permitir a devolução de uma impressão digital válida para a solicitação do cliente openssl e adulterar a seguinte solicitação de wget.     

por James Mitch 27.06.2012 / 10:16

6 respostas

28

Fonte

Instale o software necessário:

apt-get install ca-certificates curl

Faça o download do certificado SSL público:

openssl s_client -connect torproject.org:443 -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt >./x.cert </dev/null

Ou melhor:

echo -n | openssl s_client -connect torproject.org:443 -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./torproject.pem

Obtenha a impressão digital SHA-1:

openssl x509 -noout -in torproject.pem -fingerprint -sha1

Obtenha a impressão digital SHA-256:

openssl x509 -noout -in torproject.pem -fingerprint -sha256

Compare manualmente as impressões digitais SHA-1 e SHA-256 com FAQ do torproject.org: SSL .

.

Opcionalmente, torne os certificados ca inúteis para fins de teste. Usando curl aqui, mas wget tem um bug Bug e usa os arquivos ca de qualquer maneira.

sudo mv /usr/share/ca-certificates /usr/share/ca-certificates_

Faça o download com curl e o certificado fixado:

curl --cacert ./torproject.pem https://check.torproject.org/ > check.html
    
por James Mitch 17.10.2012 / 03:07
9

No tcsh:

echo | openssl s_client -connect host.example.com:443 |& openssl x509 -fingerprint -noout
    
por user273818 30.10.2015 / 12:14
8

Isso também é suficiente:

openssl x509 -fingerprint -in server.crt
    
por rundekugel 10.10.2014 / 22:45
3

Isso é bastante fácil de fazer com o comando openssl e sua funcionalidade de cliente.

O script a seguir tomará um determinado domínio (sem prefixo https) e uma impressão digital SHA-1 e sairá sem erro (0) se a impressão digital recuperada corresponder, mas com o código de saída 1 se não houver correspondência. Você pode incorporá-lo ao seu script simplesmente testando o último código de saída $? :

#!/bin/bash
FPRINT='echo -n | openssl s_client -connect :443 2>/dev/null \| openssl x509 -noout -fingerprint | cut -f2 -d'='' if [ "" = "$FPRINT" ]; then exit 0 else exit 1 fi
    
por ish 14.09.2012 / 08:29
3

source

#!/usr/bin/perl
# https://security.stackexchange.com/questions/20399/how-to-verify-the-ssl-fingerprint-by-command-line-wget-curl
# 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 descrito na documentação do Net :: SSLeay, esse método significa verificação após a transação HTTP e, portanto, não deve ser usado se você quiser verificar se está falando com o servidor certo antes de enviar os dados. Mas se tudo o que você está fazendo é decidir se deve ou não confiar no que você acabou de baixar (o que parece que você é da sua referência # 4), tudo bem.

    
por James Mitch 17.10.2012 / 03:11
1

Esse é o meu roteiro diário:

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

Ouput:

* Server certificate:
*    subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=www.google.com
*    start date: 2016-01-07 11:34:33 GMT
*    expire date: 2016-04-06 00:00:00 GMT
*    issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*    SSL certificate verify ok.
* Server GFE/2.0 is not blacklisted
* Connection #0 to host www.google.com left intact
    
por Antonio Feitosa 15.01.2016 / 14:29