Date de publication du RFC : Mai 2015
Auteur(s) du RFC : Y. Sheffer (Intuit), R. Holz (TUM), P. Saint-Andre (&yet)
Première rédaction de cet article le 6 mai 2015
Le protocole de sécurité TLS sécurise aujourd'hui, par la cryptographie, un grand nombre de communications par l'Internet. Le protocole et ses mises en œuvre dans des bibliothèques comme OpenSSL ont eu plusieurs failles, réparées au fur et à mesure. Mais les plus grosses failles restent dans l'utilisation pratique de TLS : programmeurs et administrateurs systèmes font des erreurs qui affaiblissent la sécurité de TLS. Ce RFC, le deuxième du groupe UTA (utilisation de TLS par les applications) résume les bonnes pratiques qui devraient être suivies en matière de sécurité pour que TLS atteigne complètement ses objectifs. (Il a depuis été remplacé par le RFC 9325.)
TLS est normalisé dans le RFC 5246. Ce RFC documente la version 1.2 et la 1.3 est en cours de normalisation. Il est surtout connu pour sa sécurisation de HTTP, nommée HTTPS. Mais il sert aussi pour sécuriser SMTP, XMPP, IMAP, etc. TLS lui-même ne marche que sur TCP mais il a un équivalent pour UDP, nommé DTLS, et normalisé dans le RFC 6347. Si un attaquant veut casser la protection qu'offre TLS (par exemple pour accéder au contenu en clair d'une communication normalement chiffrée), il peut viser (le RFC 7457 donne une bonne liste) :
Bref, l'analyse de sécurité de TLS est complexe et on voit pourquoi il faut se méfier comme de la peste des résumés journalistiques qui annoncent une faille TLS alors qu'il ne s'agissait que d'une bogue dans une bibliothèque.
Le RFC 7457 décrivait déjà les failles, avec plein d'exemples. Notre nouveau RFC se concentre sur les recommandations. Il définit un plancher de sécurité (pas un plafond : on peut toujours être plus strict que ce que définit le RFC). D'autre part, le RFC prévient évidemment que ces recommandations évolueront avec le temps.
Le cœur de notre RFC n'est donc pas l'analyse des risques, mais les recommandations pratiques (sections 3 et suivantes). D'abord, sur la version du protocole :
Si un client TLS a un mécanisme de repli (on tente de se connecter avec la version N, ça échoue, on ré-essaie avec N-1, ce qui se nomme la downgrade dance), on ne doit jamais se replier vers SSL. Autrement, un Homme du Milieu aurait juste à faire échouer la connexion initiale, pour garantir l'utilisation d'un protocole faible (notez que le RFC 7507 fournit une solution contre ce repli). Aux dernières nouvelles, seuls 3 % des serveurs Web TLS/SSL de l'Internet étaient SSL-seulement.
Lorsque client et serveur essaient de se connecter avec TLS mais acceptent des connexions sans TLS, des attaques actives peuvent forcer un repli vers la connexion sans TLS, en clair et pas sécurisée du tout (la négociation de TLS n'est pas elle-même protégée par TLS). Pour éviter cela, client et serveur devraient insister sur l'utilisation de TLS et utiliser des techniques comme HSTS (RFC 6797) pour signaler qu'on sait faire du TLS et qu'il ne faut pas essayer en clair.
Plusieurs attaques sont facilitées par l'utilisation de la compression (RFC 5246, section 6.2.2), comme CRIME. Il est recommandé de la couper, sauf si on est sûr que le protocole applicatif qui utilise TLS n'est pas vulnérable à ces attaques.
L'établissement d'une session TLS nécessite d'échanger plusieurs paquets, ce qui prend du temps. Pour limiter ce problème, TLS dispose d'un mécanisme de reprise de session (RFC 5246). Ce mécanisme doit être autant protégé que le serait une session normale. Par exemple, dans le cas du RFC 5077, si on chiffrait le ticket utilisé pour la reprise de session avec un algorithme bien plus faible que celui utilisé dans la session elle-même, un attaquant pourrait choisir de tenter une « reprise » d'une session inexistante, court-circuitant ainsi l'authentification. À noter aussi que ce mécanisme de reprise de session peut annuler l'effet de la forward secrecy : si l'attaquant met la main sur les tickets, il peut déchiffrer les sessions qu'il a enregistré (cf. section 3.4 de notre RFC). Il faut donc changer les clés des tickets de temps en temps.
L'extension de renégociation sécurisée du RFC 5746 doit être disponible (ou, sinon, il faut couper la renégociation).
Une dernière recommandation générale porte sur SNI (RFC 6066, section 3). Bien que cela n'affecte pas directement la sécurité, cette extension est recommandée, pour des protocoles comme HTTPS, car elle permet des politiques de sécurité plus souples et donc plus implémentables (comme d'avoir un certificat par site Web).
La section 3 de notre RFC portait sur des recommandations
générales. La section 4 s'attaque aux algorithmes de cryptographie
(cipher suites). Ceux-ci s'usent avec le temps,
quand les progrès de la cryptanalyse exposent
leurs failles. Cette usure se fait à un rythme très variable :
certains algorithmes durent depuis longtemps, d'autres ont été éliminés
rapidement. Mais aucun algorithme n'est éternel et voilà pourquoi il
est nécessaire de séparer le protocole des algorithmes, ce qu'on nomme
l'« agilité cryptographique ». Notre RFC recommande donc de ne pas
utiliser l'algorithme NULL
, qui ne chiffre pas du
tout (pas besoin de cryptanalyse pour le casser...) et n'a d'intérêt
que pour les tests et le
débogage. Plus récemment, les progrès de la cryptanalyse,
documentés dans le RFC 7465, ont montré que
RC4 ne devait pas être
utilisé non plus. Le problème des algorithmes trop faibles est aggravé
par l'action des États qui veulent pouvoir espionner les
communications et qui imposent, dans certains cas, l'utilisation
d'algorithmes dont les faiblesses sont connues. C'est le cas aux
États-Unis des algorithmes dit export (car ils
étaient les seuls légalement exportables à une époque). Si ces
algorithmes sont présents, l'attaque FREAK
permettra à un attaquant actif de les sélectionner, flanquant en l'air
toute la sécurité de TLS.
Les révélations de Snowden ont montré que la NSA (et peut-être d'autres organisations) enregistre de nombreuses communications chiffrées qu'elle ne sait pas décrypter. L'idée est que si, un jour, on met la main sur la clé privée (par perquisition physique, piratage de l'ordinateur à distance ou tout autre méthode), on pourra alors déchiffrer et certaines de ces communications seront encore intéressantes. Pour éviter cela, notre RFC conseille de privilégier les algorithmes qui mettent en œuvre la forward secrecy comme la famille DHE.
Quels algorithmes restent-ils après ces nombreuses éliminations ?
Notre RFC en mentionne quatre (après une discussion longue et acharnée
à l'IETF) :
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
et
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
. Ils
utilisent DHE ou ECDHE, avec
RSA, AES en mode
GCM (voir RFC 5288 section 6, sur la
sécurité de ce mode) et SHA-2. Ils font
tous du chiffrement intègre (authenticated
encryption, RFC 5116). Tout logiciel TLS devrait
être configuré pour préferer ces algorithmes (cf. « Applied
Crypto Hardening »).
Attention, notre RFC parle uniquement de préférer ces algorithmes,
pas de les imposer. Pour permettre l'interopérabilité, TLS a en effet
des algorithmes obligatoires, qui doivent être mis en œuvre dans
chaque bibliothèque TLS. C'est le cas de
TLS_RSA_WITH_AES_128_CBC_SHA
, obligatoire mais
pas le plus fort, loin de là. Mais on peut compter sur lui puisqu'il
est obligatoire, contrairement aux quatre algorithmes cités plus haut, qui
peuvent ne pas être présents. Il peut donc être nécessaire d'arbitrer
entre interopérabilité et sécurité...
Ce RFC a également des recommandations sur les clés publiques utilisées dans les certificats : 2 048 bits au moins en RSA (ce qui est imposé par la plupart des AC depuis un certain temps, c'est le cas de CAcert, par exemple), et SHA-256 pour condenser la clé (et plus SHA-1).
Un petit mot en passant sur un point abordé dans la section 5. Celle-ci concerne l'« applicabilité » des recommandations faites ici. Cette applicabilité est très large, quasiment tous les usages de TLS sont concernés. Il existe un usage fréquent de TLS, parfois appelé « chiffrement opportuniste » (RFC 7435) où une des parties qui communiquent va essayer de faire du TLS mais, si cela ne marche pas (par exemple parce que l'autre partie ne gère pas le chiffrement), on se rabat sur une communication en clair. Dans ce contexte, certaines des recommandations du RFC peuvent être trop strictes. Par exemple, on a vu qu'il ne fallait pas utiliser RC4, trop faible cryptographiquement. Si on prend au pied de la lettre cette recommandation, qu'une des deux parties ne connait que RC4 et qu'on est dans un contexte de chiffrement opportuniste, on pourrait arriver à ce résultat paradoxal que, RC4 étant refusé, on communique en clair, ce qui est certainement bien pire que le plus mauvais des algorithmes de cryptographie. Il peut donc être nécessaire de dévier des recommandations de notre RFC 7525.
Enfin, pour terminer ce RFC déjà riche, une section 6
consacrée à divers problèmes de sécurité qui n'avaient pas été traités
avant. D'abord, la nécessité, lorsqu'on vérifie un certificat, de
vérifier également que le nom du serveur, dans le certificat,
corespond au nom auquel on voulait se connecter. Cela parait évident
mais ce n'est pas toujours fait par la bibliothèque qu'on utilise (cf.
mon
exposé à Devoxx - et ses
transparents - pour des exemples.) Il peut donc être utile que
l'application fasse la validation elle-même, sans quoi un attaquant
actif peut détourner le trafic chiffré, de manière triviale. La
section 3 du RFC 2818 et le RFC 6125
détaillent ce qu'il faut exactement valider. Bien sûr, pour que cette
validation ait un sens, il faut que le nom du serveur ait lui-même été
obtenu de manière sûre. Si on a cliqué sur un lien
https://...
dans un message de
hameçonnage, vérifier que le nom est correct
n'aide pas tellement (« oui, c'est bien
secure-serious-bank.ab451e239f.ru
»). Idem si le
nom vient d'une requête DNS (par exemple de type
MX) non sécurisée par DNSSEC.
J'ai déjà parlé plus haut de la forward secrecy, une propriété qui fait que le vol des clés privées a posteriori est inutile, même pour un attaquant qui avait enregistré les communications chiffrées. Dans la vie, ce vol peut arriver pour des tas de raisons, machines jetées à la poubelle sans les avoir effacées, et récupérées par un indiscret, clés trop faibles face à la force brute (cf. « Mining Your Ps and Qs: Detection of Widespread Weak Keys in Network Devices »), clé générée par un tiers (dans le « cloud ») et ensuite obtenue par piratage, attaque violente et/ou légale contre les administrateurs système pour obtenir la clé, et toutes les autres méthodes d'accès aux clés privées qui peuvent exister. La forward secrecy n'empêche pas ces attaques mais elle empêche l'attaquant d'exploiter son succès. Elle s'obtient en général en faisant un échange Diffie-Hellman. Dans le contexte de la sécurité de TLS, le principal problème est que beaucoup d'algorithmes utilisés ne permettent pas le forward secrecy, et que les autres, les bons, ne sont pas sélectionnés en priorité.
L'authentification du serveur TLS (on peut aussi authentifier le client mais c'est plus rare) repose presque toujours sur un certificat X.509. Si la clé privée associée au certificat est volée, le mécanisme de sécurité de X.509 est la révocation (RFC 5280, section 3.3). On sait que ce mécanisme nécessite une bonne connexion Internet, et est peu fiable : les listes de certificats révoqués, à distribuer partout, ne passent pas à l'échelle, le protocole OCSP (RFC 6960) est souvent bloqué (et il pose de toute façon des problèmes de passage à l'échelle et de vie privée), menant les clients à ignorer les échecs OCSP, etc. Il existe des solutions partielles (section 8 du RFC 6066, RFC 6961, RFC 6698) mais pas assez déployées.
Si vous voulez lire des recommandations en français sur la
configuration de TLS, il y a deux guides ANSSI
qui sont en rapport avec ce RFC, le RGS
pour les algorithmes de cryptographie, et le guide
pour la sécurité des sites Web, avec des recommandations
précises pour OpenSSL (SSLCipherSuites
Apache).
Et pour terminer sur une note personnelle, si vous regardez la configuration HTTPS de mon blog, elle est actuellement perturbée par deux sérieuses bogues du module GnuTLS d'Apache : #754960 et #642357.
Merci à Manuel Pégourié-Gonnard pour une relecture attentive qui a permis de trouver plusieurs erreurs. D'autres bonnes lectures :
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)