Le HTTPS, c'est la version « sécurisée » (c'est-à-dire, chiffrée et signée/authentifiée) du protocole HTTP utilisé de façon générale pour véhiculer le Web. Pour Madame Michu, le HTTPS se manifeste par un petit cadenas fermé affiché quelque part par le navigateur et probablement par la sensation confortable que les données qu'on échange sont protégées (donc que le méchant hacker russe ne peut pas lire votre numéro de carte de crédit en passant). L'idée est bonne. La crypto est raisonnable. Malheureusement, l'implémentation — la péri-crypto, pourrait-on dire, ou, en fait, la politique — est épouvantable, à tel point que ce truc est tout simplement à jeter à la poubelle. Le problème est simple : tout le HTTPS du Web est basé sur une chaîne de confiance, dont la source (les autorités racines) ne fait absolument pas son travail, voire, se comporte comme des escrocs méritent exactement zéro confiance, ce qui, inévitablement, ramène à zéro la confiance qu'on peut avoir en tout le reste de l'édifice construit sur ces fondations pourries.
Le principe, c'est que pour établir une connexion sécurisée (chiffrée), les deux partenaires (le client, donc le navigateur Web qui veut accéder au site sécurisé, et le serveur de ce site sécurisé) s'identifient l'un à l'autre (en pratique, en fait, c'est généralement seulement le serveur qui s'identifie auprès du client) en échangeant des certificats qui permettent que chacun soit sûr de parler à la bonne personne et d'en connaître la bonne clé publique de chiffrement, pour pouvoir ensuite se mettre d'accord sur une clé. Le serveur, pour s'authentifier auprès du client, va fournir une chaîne de signatures : sa clé publique, avec son nom officiel et le nom du site qu'il opère, sont signés par une autorité avec une clé elle-même signée par une autre, et ainsi de suite jusqu'à une autorité racine que le navigateur connaît nativement. Dans la pratique, ces autorités intermédiaires sont du bidon, on peut faire comme si l'identité du site était signée directement par l'autorité racine. Tout ceci prend place dans le cadre défini par une moussaka géante appelée X.509.
Si les autorités racines faisaient un boulot un tant soit peu
sérieux, et si Madame Michu comprenait ce qui se passe, ce système ne
serait peut-être pas si mauvais. Le but est de se prémunir contre
deux sortes de risques : le premier est l'attaque par un espion passif
(eavesdropper) qui ne peut qu'espionner les
communications sans les altérer : il s'agit du risque le plus
vraisemblable, et pour ça on connaît en fait une méthode bien plus
simple permettant d'assurer une communication privée résistante aux
espion passifs sans même à avoir à authentifier les participants,
c'est le
protocole d'échange de clés de Diffie-Hellman ; l'autre risque,
moins vraisemblable sur Internet mais aussi plus difficile à éviter et
où il faut vraiment établir l'identité des participants, c'est
l'attaque
de l'homme au milieu
(man-in-the-middle), c'est-à-dire un
espion qui peut intercepter complètement la communication
entre A et B et se faire passer
pour A auprès de B et pour B auprès
de A en recopiant les données mais en changeant les clés.
J'estime que les attaques man-in-the-middle sont
assez peu probables sur Internet, mais si on veut s'en protéger, il
faut effectivement utiliser un système qui permet d'identifier
l'interlocuteur et pas seulement de sécuriser un canal avec lui. Donc
le principe général de HTTPS et de ses chaînes de
signatures n'est pas absurde.
Les problèmes sont multiples. Un problème zéro est que Madame
Michu n'a rien à faire de comprendre ces histoires de chiffrement et
de signature, elle veut savoir si elle peut avoir confiance dans le
site Web et dans la connexion : l'architecture garantit peut-être que
la connexion soit sécurisée, éventuellement que le site Web soit bien
qui il indique qu'il est, mais certainement pas qu'il est honnête ni
même qu'il n'est pas quelqu'un d'autre avec un nom très subtilement
semblable et avec lequel Madame Michu va probablement confondre. Dans
cette optique, le problème principal est que les autorités racines ne
font pas du tout ce qu'on attend d'elles. On attend d'elles (si on
veut que le système fonctionne un peu) qu'elles vérifient
soigneusement l'identité des personnes à qui elles délivrent des
certificats, qu'elles vérifient que le nom ne prête pas à confusion,
qu'il s'agit d'une compagnie vraiment implantée et pas d'un petit
malin qui a fondée une association Société Généralle
sans aucun
rapport avec la Société Générale, etc. Ce que font en réalité les
autorités racines, c'est recevoir de l'argent (parfois beaucoup) et
mettre leur tampon sur les certificats sans regarder quoi que ce soit.
Dès lors, le système est une pure escroquerie. Même si toutes les
autorités racines ne sont pas des escrocs, il suffit qu'une seule le
soit pour que tout le système soit pourri — or il y en a toute
une ribambelle et on ne sait pas très bien, d'ailleurs, par quel
processus elles sont choisies (cela dépend du navigateur : Firefox
est un
peu transparent sur la question, mais les autres navigateurs
carrément moins, et certains aussi se contenent de recevoir de
l'argent (toujours beaucoup) et mettre le certificat demandé parmiles
certificats racines).
À ce compte-là — tant qu'à avoir un système qui ne vérifie
rien, finalement, que le nom de domaine — on aurait pu faire
plus simple et moins cher : avoir un système de signature qui suive le
mécanisme hiérarchique du DNS : en achetant le
domaine madore.org
je recevrais automatiquement un
certificat prouvant que je suis bien propriétaire du domaine en
question, et signé par la clé du domaine org
. C'est
effectivement ce qui va se faire avec
le DNS
sécurisé, mais pour autant que je comprenne il n'est
malheureusement pas prévu que ce système hiérarchique soit directement
utilisable dans les navigateurs Web (probablement pour ne pas tuer la
poule aux œufs d'or des escrocs qui détiennent des certificats
racines).
Idéalement, le système que je voudrais avoir, moi (mais que je
conviendrait probablement pas trop à Madame Michu), quand je me
connecterais à un site sécurisé, il me dirait : bonjour, ceci est
la première fois que vous vous connectez à un site du
domaine
avec des options diverses permettant, par exemple, de marquer qu'on
veut continuer la connexion mais sans faire confiance à la sécurité de
la connexion (rappeler si besoin est que le canal n'est pas forcément
sûr), ou je ne sais quoi du genre. (À tout le moins, même en
l'absence de signature identifiant l'interlocuteur, on aurait une
protection contre les espions passifs en utilisant un échange de type
Diffie-Hellman, ce qui n'est déjà pas mal.) Quand le certificat
expirerait (arriverait au bout de sa date de validité), j'aurais un
message semblable me signalant de plus que le nouveau certificat
utilise la même clé que précédemment ou est signé avec celle-ci (ce
qui augmente ma confiance). Et surtout, si jamais le certificat
change sans raison, même si le nouveau est signé par des autorités
censément de confiance, j'aurais droit à un message expliquant la
situation. C'est, grosso modo, les signatures en moins, comment
fonctionne SSH.exemple.tld
: le certificat qui l'authentifie a
été signé par <telle autorité> et <telle autorité> et
<telle autorité> : voulez-vous continuer à vous connecter ?
Mais le HTTPS, en tout cas tel qu'il est implémenté dans les navigateurs, ne fonctionne pas du tout comme ceci. D'abord, ce système irrémédiablement mal foutu ne permet à un certificat d'être signé que par une autorité : on établit une chaîne de confiance et pas un réseau de confiance : pas moyen, donc, pour un site Web de faire signer son certificat par plusieurs autorités (ou par sa précédente clé en cas de changement) pour combiner un peu la confiance très limitée que j'apporte en chacune. Ensuite, on ne peut faire confiance que totalement ou pas du tout : si je donne ma confiance à une autorité, je ne serai pas prévenu d'un changement apporté au certificat d'un site que je consulte ; pas moyen, non plus, d'avoir un message particulier à la première connexion sauf à refuser complètement la confiance en l'autorité racine. Tout ceci est totalement nul.
Sur un de mes ordinateurs, j'ai fait l'expérience de retirer la confiance accordée par mon Firefox à tous les certificats des autorités racines. D'abord, ce n'est pas du tout facile à faire, même s'il y a peut-être eu des progrès depuis dans Firefox (dans Edit → Preferences → Advanced → Encryption → Certificats → View Certificates → Authorities on peut régler des choses) ; j'ai gribouillé les notes suivantes, qui donnent une idée de combien c'est mal foutu :
### TO LIST DEFAULT ROOT CERTIFICATES:
cd "`mktemp -d`"
# Create a new certificate database:
certutil -N -d .
# (type return twice for empty password)
# Add roots from libnssckbi:
modutil -add roots -libfile /usr/lib/nss/libnssckbi.so -dbdir .
# replace /usr/lib/nss/libnssckbi.so by wherever libnssckbi is found on your system
# (confirm: this is a temporary directory so there is no danger)
# Check that the Builtin Object Token was added:
modutil -list -dbdir .
# Now you can list the contents of the Builtin Object Token:
certutil -L -d . -h "Builtin Object Token"
### TO UNTRUST ROOT CERTIFICATES:
# (Make sure Firefox is not running!)
cd .mozilla/firefox/$salt
# (replace $salt by wherever your profile is stored)
modutil -add roots -libfile /usr/lib/nss/libnssckbi.so -dbdir .
# (same comment as above for libnssckbi.so,
# but this time really make sure the browser is not running!).
TEMPFILE="`mktemp`"
certutil -L -d . -h "Builtin Object Token" | perl -ne 'next unless /^(.*?)\s+([A-Za-z]*\,[A-Za-z]*\,[A-Za-z]*)\s*$/; $n=$1; $v=$2; $v=~s/C/c/g; $v=~s/G//g; $v=~s/T/c/g; print "certutil -M -d . -n \"$n\" -t \"$v\"\n";' > "$TEMPFILE"
# Review or edit $TEMPFILE and possibly run it with:
. "$TEMPFILE"
Ensuite, évidemment, se connecter la première fois à n'importe quel
site HTTPS conduit à un avertissement : ça c'est l'effet
désiré, et je ne m'en plains pas. Je me plains, en revanche, du fait
que cet avertissement est peu utile, et notamment il n'est pas du tout
évident d'arriver à voir si la signature par l'autorité racine est
valable ou non (je ne veux pas faire
confiance automatiquement à une autorité racine, mais je veux
quand même savoir si elle a ou non signé le certificat). Mais
surtout, il y a pire : autant les choses se passent raisonnablement
bien quand on essaie explicitement de se connecter à un
site HTTPS (en entrant une URL
en https://
ou en suivant un lien), autant quand c'est un
script ou une image ou quelque chose comme ça que le navigateur essaie
de charger depuis un domaine dont on n'a jamais accepté le certificat,
la connexion échoue purement et simplement (ou alors avec une fenêtre
d'avertissement qui ne propose qu'une seule option : faire échouer
l'opération). Voilà qui est profondément crétin ! Même si le
navigateur ne fait qu'aller chercher une erreur ou un bout de
JavaScript à une adresse en https://
, je veux voir la
même page me proposant de voir le certificat et de choisir si je veux
l'accepter ou non ! (Je me suis rendu compte du problème en essayant
d'accéder à un site qui utilisait
un CAPTCHA
en https://
,
probablement ReCAPTCHA,
et qui n'apparaissait tout simplement pas. Du coup, je ne pouvais
rien faire et j'ai mis un temps fou à comprendre ce qui se passait.)
Il y a aussi des problèmes bizarres avec les extensions Firefox, qui
n'ont pas l'air de se mettre à jour correctement (sans pour autant
signaler à l'utilisateur qu'il est face à tel certificat signé de
telle et telle manière) si on détruit la confiance dans les
certificats racines. Bref, cela conduit à plein de problèmes, donc on
est quasiment obligé d'accepter ces autorités racines…
…Sans pour autant que ça aide Madame Michu, qui risque tout
à fait de tomber sur le domaine amazoon.com
présentant un
certificat en bonne et due forme signé par n'importe quelle autorité
racine (donc montrant à Madame Michu le petit cadenas fermé qui lui
inspire confiance) et qui ressemble comme deux gouttes d'eau
à amazon.com
mais qui appartient à une compagnie moins
scrupuleuse. Madame Michu ne peut rien dire : le certificat montrait
bien qu'elle était chez la compagnie Amazoon avec deux
‘o’, et l'autorité racine ne s'est jamais engagée à
vérifier qu'il n'y avait pas ce genre de confusion. Tout ce système
est à foutre à la poubelle.
Mise à jour : une entrée plus tardive sur ce même sujet (ou proche).