Utilisation d'un téléchargeur de site Web en ligne de commande, tel que wget
, curl
ou tout autre ... Dans un script ...
J'ai les empreintes digitales certifiantes d'un site web SHA-1 et SHA-256. Pour des raisons de sécurité ( 1 ) ( 2 ), je ne souhaite pas utiliser le système public d'autorité de certification SSL. L'empreinte doit être codée en dur.
Une application comme wget peut-elle vérifier l’empreinte SSL?
wget n'a pas une telle fonctionnalité. ()
En utilisant wget --ca-certificate
ou curl --cacert
, je devrais utiliser ma propre autorité de certification locale, ce que j'aimerais éviter, car cela ajoute beaucoup de complexité. C'est aussi très difficile et personne ne l'a jamais fait auparavant. ( 4 )
N'y a-t-il aucun outil, commedownload --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz https://site.com
?
La solution ne doit bien sûr pas être vulnérable à TOCTOU. ( 5 ) Le MITM pourrait laisser une empreinte valide pour la demande du client openssl et falsifier la demande wget suivante.
Installez le logiciel requis:
apt-get install ca-certificates curl
Téléchargez le certificat SSL public:
openssl s_client -connect torproject.org:443 -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt >./x.cert </dev/null
Ou mieux:
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
Obtenir l'empreinte SHA-1:
openssl x509 -noout -in torproject.pem -fingerprint -sha1
Obtenez l'empreinte SHA-256:
openssl x509 -noout -in torproject.pem -fingerprint -sha256
Comparez manuellement les empreintes digitales SHA-1 et SHA-256 avec FAQ de torproject.org: SSL .
.
Rendre éventuellement les certificats de certification inutiles à des fins de test. En utilisant curl ici, mais wget a un bug Bug et utilise les fichiers ca de toute façon.
Sudo mv /usr/share/ca-certificates /usr/share/ca-certificates_
Télécharger avec curl et le certificat épinglé:
curl --cacert ./torproject.pem https://check.torproject.org/ > check.html
En tcsh:
echo | openssl s_client -connect Host.example.com:443 |& openssl x509 -fingerprint -noout
Cela suffit aussi:
openssl x509 -fingerprint -in server.crt
Ceci est assez facile à faire avec la commande openssl
et ses fonctionnalités client.
Le petit script suivant prendra un domaine donné (pas de préfixe https) et une empreinte SHA-1, et se terminera sans erreur (0) si l'empreinte récupérée correspond, mais avec le code de sortie 1 s'il n'y a pas de correspondance. Vous pouvez ensuite l'intégrer à votre script en testant simplement le dernier code de sortie $?
:
#!/bin/bash
FPRINT = `echo -n | openssl s_client -connect $ 1: 443 2>/dev/null\| openssl x509 -noout -fingerprint | cut -f2 -d '=' ` if [" $ 2 "=" $ FPRINT "]; puis sortie 0 sinon sortie 1 fi
#!/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;
}
Comme indiqué dans la documentation Net :: SSLeay, cette méthode signifie une vérification après la transaction HTTP et ne doit donc pas être utilisée si vous souhaitez vérifier que vous communiquez avec le bon serveur avant de leur envoyer des données. Mais si tout ce que vous faites est de décider s'il faut ou non faire confiance à ce que vous venez de télécharger (cela ressemble à de votre référence 4), c'est très bien.
C'est mon script de tous les jours:
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