{"id":360,"date":"2025-06-05T19:19:28","date_gmt":"2025-06-05T19:19:28","guid":{"rendered":"https:\/\/tolva.fr\/?p=360"},"modified":"2025-06-05T19:21:33","modified_gmt":"2025-06-05T19:21:33","slug":"le-protocole-tls-explique-a-mon-chat","status":"publish","type":"post","link":"https:\/\/tolva.fr\/index.php\/2025\/06\/05\/le-protocole-tls-explique-a-mon-chat\/","title":{"rendered":"Le protocole TLS expliqu\u00e9 \u00e0 mon chat"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>TLS vu d&rsquo;avion<\/strong><\/h2>\n\n\n\n<p>TLS (Transport Layer Security) est un protocole cryptographique permettant d&rsquo;\u00e9changer des donn\u00e9es de mani\u00e8re s\u00e9curis\u00e9e au-dessus d&rsquo;une session TCP \u00e9tablie entre un client et un serveur.<\/p>\n\n\n\n<p>Les services offerts par TLS sont les suivants :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Authentification du serveur et optionnellement du client,<\/li>\n\n\n\n<li>Chiffrement des donn\u00e9es garantissant leur confidentialit\u00e9,<\/li>\n\n\n\n<li>Integrit\u00e9 des donn\u00e9es.<\/li>\n<\/ul>\n\n\n\n<p>De nombreux protocoles applicatifs pr\u00e9existants ont une variante transport\u00e9e par TLS, faisant de TLS un des piliers d&rsquo;Internet : HTTPS (HTTP sur TLS, sur le port 443), LDAPS (LDAP sur TLS, port 636) et ainsi de suite.<\/p>\n\n\n\n<p>TLS est un standard maintenu par l&rsquo;IETF et est le descendant du protocole SSL (Secure Sockets Layer). L&rsquo;acronyme SSL continue d&rsquo;\u00eatre employ\u00e9 pour d\u00e9signer TLS.<\/p>\n\n\n\n<p>Les RFC d\u00e9crivant TLS sont grosso modo d\u00e9coup\u00e9es en trois sous-protocoles :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le <em>TLS Record Protocol<\/em>, d\u00e9crivant le format des messages,<\/li>\n\n\n\n<li>Le <em>Handshake<\/em>, certainement la partie la plus complexe et centrale de TLS,<\/li>\n\n\n\n<li>Les alertes, qui sont des messages d&rsquo;erreur.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Historique<\/strong><\/h2>\n\n\n\n<p>SSL a \u00e9t\u00e9 cr\u00e9\u00e9 par la soci\u00e9t\u00e9 Netscape et est devenu TLS en \u00e9tant standardis\u00e9 par l&rsquo;IETF.<\/p>\n\n\n\n<p>Netscape \u00e9tait l&rsquo;\u00e9diteur du navigateur du m\u00eame nom, qui fut le premier navigateur web diffus\u00e9 \u00e0 grande echelle, avant d&rsquo;\u00eatre supplant\u00e9 par Internet Explorer.<\/p>\n\n\n\n<p>Assez t\u00f4t, le besoin de garantir la s\u00e9curit\u00e9 des \u00e9changes de donn\u00e9es se manifesta, notamment pour le commerce \u00e9lectronique. Ce besoin motiva la cr\u00e9ation de SSL au milieu des ann\u00e9es 1990.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>SSLv1<\/strong><\/h3>\n\n\n\n<p>La toute premi\u00e8re version de SSL a \u00e9t\u00e9 \u00e9labor\u00e9e en 1994. On trouve tr\u00e8s peu d&rsquo;informations sur SSLv1. En effet, le protocole comportait des vuln\u00e9rabilit\u00e9s si graves qu&rsquo;il n&rsquo;est jamais sorti de Netscape.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>SSLv2<\/strong><\/h3>\n\n\n\n<p>Publi\u00e9e en 1995, SSLv2 fut la toute premi\u00e8re version de SSL r\u00e9ellement utilis\u00e9e. Cette version comporte elle aussi de tr\u00e8s s\u00e9rieuses vuln\u00e9rabilit\u00e9s de conception :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Les sessions peuvent \u00eatre facilement termin\u00e9es par un attaquant en position de MitM (Man-in-the-Middle) : il lui suffit d&rsquo;injecter un <code>TCP FIN<\/code>.<\/li>\n\n\n\n<li>La m\u00eame cl\u00e9 de session est utilis\u00e9e pour le chiffrement et l&rsquo;integrit\u00e9 des donn\u00e9es : si un algorithme de chiffrement faible est n\u00e9goci\u00e9, l&rsquo;integrit\u00e9 peut \u00e9galement \u00eatre compromise.<\/li>\n\n\n\n<li>L&rsquo;integrit\u00e9 est assur\u00e9e par un calcul du style <code>h = MD5(k + M)<\/code>, o\u00f9 <code>k<\/code> est la cl\u00e9 de session, <code>M<\/code> le message \u00e0 authentifier et <code>+<\/code> d\u00e9signe la concat\u00e9nation. Ce type de construction est \u00e0 proscrire, car un attaquant connaissant <code>h<\/code> peut forger <code>h1 = MD5(k + M + M1)<\/code> afin de remplacer <code>(M, h)<\/code> par <code>(M + M1, h1)<\/code>.<\/li>\n\n\n\n<li>L&rsquo;integrit\u00e9 du handshake n&rsquo;est pas assur\u00e9e par un message <code>Finished<\/code> contenant un r\u00e9sum\u00e9 cryptographique des messages du handshake (il y a bien des messages <code>ClientFinished<\/code> et <code>ServerFinished<\/code> mais ils ne contiennent pas de r\u00e9sum\u00e9 cryptographique sur le handshake). Cela permet \u00e0 un attaquant en position de MitM de manipuler le handshake et par exemple de modifier \u00e0 la baisse les algorithmes de chiffrement n\u00e9goci\u00e9s.<\/li>\n<\/ul>\n\n\n\n<p>Pour toutes ces raisons, SSLv2 ne doit plus \u00eatre utilis\u00e9. \u00c7a tombe bien, il est \u00e0 peu pr\u00e8s abandonn\u00e9 aujourd&rsquo;hui (en partie gr\u00e2ce \u00e0 la RFC 6176) et l&rsquo;on ne s&rsquo;attardera donc pas dessus.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>SSLv3<\/strong><\/h3>\n\n\n\n<p>SSLv3 est une refonte majeure destin\u00e9e \u00e0 corriger les nombreuses erreurs de jeunesse de SSLv2. Cette version, relativement proche des suivantes (jusqu&rsquo;\u00e0 TLSv1.3) a \u00e9t\u00e9 publi\u00e9e en 1996.<\/p>\n\n\n\n<p>Elle a fait l&rsquo;objet de la RFC 6101 en 2011, qui est une RFC \u00e0 vocation \u00ab\u00a0historique\u00a0\u00bb.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>TLSv1.0<\/strong><\/h3>\n\n\n\n<p>TLSv1.0 est le r\u00e9sultat de la normalisation de SSLv3 par l&rsquo;IETF dans la RFC 2246, publi\u00e9e en 1999. M\u00eame s&rsquo;il n&rsquo;y a pas de changement fondamental entre SSLv3 et TLSv1.0, il y a quelques diff\u00e9rences \u00ab\u00a0subtiles\u00a0\u00bb emp\u00eachant l&rsquo;interop\u00e9rabilit\u00e9.<\/p>\n\n\n\n<p>Les principales diff\u00e9rences entre SSLv3.0 et TLSv1.0 introduites lors de cette normalisation sont les suivantes :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;usage combin\u00e9 de MD5 et SHA-1 dans plusieurs op\u00e9rations cryptographiques (calcul du <code>master_secret<\/code> \u00e0 partir du <code>pre_master_secret<\/code>, calcul du <code>key_block<\/code> \u00e0 partir du <code>master_secret<\/code> notamment) est remplac\u00e9 dans TLSv1.0 par une PRF.<\/li>\n\n\n\n<li>Le calcul du message <code>Finished<\/code>, initialement r\u00e9alis\u00e9 \u00e0 partir de MD5 et SHA-1 et maintenant r\u00e9alis\u00e9 avec cette PRF.<\/li>\n\n\n\n<li>Le MAC est calcul\u00e9 diff\u00e9remment.<\/li>\n\n\n\n<li>La signature pr\u00e9sente dans le message <code>CertificateVerify<\/code> (envoy\u00e9 lorsque le client s&rsquo;authentifie) est calcul\u00e9e diff\u00e9remment.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>TLSv1.1<\/strong><\/h3>\n\n\n\n<p>Cette version a \u00e9t\u00e9 normalis\u00e9e par la RFC 4346 en 2006. Les principales modifications par rapport \u00e0 TLSv1.0 sont les suivantes :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;algorithme AES est introduit.<\/li>\n\n\n\n<li>Le vecteur d&rsquo;initialisation (IV) implicite est remplac\u00e9 par un IV explicite, afin d&#8217;emp\u00eacher certaines attaques (BEAST, notamment).<\/li>\n\n\n\n<li>Les code d&rsquo;alerte envoy\u00e9s lorsqu&rsquo;un message est mal d\u00e9chiffr\u00e9 et lorsqu&rsquo;un message a un MAC incorrect sont uniformis\u00e9s, afin d&#8217;emp\u00eacher d&rsquo;\u00e9ventuels oracles de padding.<\/li>\n\n\n\n<li>Les ciphers suites EXPORT (<em>DES40<\/em>, <em>RC4_40<\/em>, <em>RC2<\/em>) et des m\u00e9canismes de key exchange EXPORT (DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, RSA_EXPORT) sont supprim\u00e9es.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>TLSv1.2<\/strong><\/h3>\n\n\n\n<p>La RFC 5246 d\u00e9crivant TLSv1.2 a \u00e9t\u00e9 publi\u00e9e en 2008. Les principales diff\u00e9rences avec la version pr\u00e9c\u00e9dentes sont :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>La <em>pseudorandom function<\/em> (PRF) utilis\u00e9e pour diverses op\u00e9rations cryptographiques a \u00e9t\u00e9 revue. Initialement bas\u00e9e sur MD5 et SHA-1, elle utilise maintenant SHA-256 ; Globalement, tous les calculs cryptographiques bas\u00e9s sur l&rsquo;utilisation conjointe de MD5 et SHA-1 sont remplac\u00e9s par l&rsquo;utilisation d&rsquo;une seule fonction de hachage.<\/li>\n\n\n\n<li>Des modes de chiffrement authentifiants ont \u00e9t\u00e9 introduits.<\/li>\n\n\n\n<li>Les suites utilisant DES et IDEA ont \u00e9t\u00e9 retir\u00e9es.<\/li>\n\n\n\n<li>Le support de AES devient obligatoire (la suite TLS_RSA_WITH_AES_128_CBC_SHA doit \u00eatre support\u00e9e).<\/li>\n\n\n\n<li>Des suites utilisant HMAC-SHA256 ont \u00e9t\u00e9 ajout\u00e9es.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>TLSv1.3<\/strong><\/h3>\n\n\n\n<p>TLSv1.3 est une refonte en profondeur du protocole dont de multiples aspects ont \u00e9t\u00e9 enti\u00e8rement repens\u00e9s :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Auparavant, les suites de cryptographiques d\u00e9finissaient l&rsquo;algorithme de chiffrement, la fonction de hachage utilis\u00e9e par le m\u00e9canisme d&rsquo;authentification, le m\u00e9canisme d&rsquo;\u00e9change du secret commun et le m\u00e9canisme d&rsquo;authentification. Dans TLSv1.3, les op\u00e9rations \u00ab\u00a0symetriques\u00a0\u00bb et les op\u00e9rations \u00ab\u00a0asym\u00e9triques\u00a0\u00bb ont \u00e9t\u00e9 d\u00e9cor\u00e9l\u00e9es et les suites cryptographiques ne d\u00e9finissent plus que l&rsquo;algorithme de chiffrement et le m\u00e9canisme assurant l&rsquo;integrit\u00e9. Seules cinq suites cryptographiques sont d\u00e9finies. Toutes garantissent la <em>Perfect Forward Secrecy<\/em> (ou PFS : la compromission de la cl\u00e9 priv\u00e9e du serveur ne permet pas de d\u00e9chiffrer le trafic captur\u00e9 auparavant).<\/li>\n\n\n\n<li>La n\u00e9gociation du m\u00e9canisme d&rsquo;authentification utilise maintenant l&rsquo;extension <code>signature_algorithms<\/code>.<\/li>\n\n\n\n<li>Les messages <code>ClientKeyExchange<\/code> et <code>ServerKeyExchange<\/code> utilis\u00e9s pour l&rsquo;\u00e9change des demi-cl\u00e9s ont \u00e9t\u00e9 remplac\u00e9s par l&rsquo;extension <code>key_share<\/code>. En fait, TLSv1.3 fait un usage massif des extensions.<\/li>\n\n\n\n<li>Une diff\u00e9rence majeure par rapport aux versions ant\u00e9rieures est que cet \u00e9change de demi-cl\u00e9s est fait AVANT l&rsquo;\u00e9tape d&rsquo;authentification : le client envoie une liste de demi-cl\u00e9s pour les groupes qu&rsquo;il supporte. Le serveur r\u00e9pond la demi-cl\u00e9 pour le groupe qu&rsquo;il a choisi et tous les messages suivants sont chiffr\u00e9s, y compris les messages de handshakes post\u00e9rieurs.<\/li>\n\n\n\n<li>Autre diff\u00e9rence majeure, la suite du handshake est chiffr\u00e9e, notamment l&rsquo;envoi du certificat.<\/li>\n\n\n\n<li>Le m\u00e9canisme de d\u00e9rivation de cl\u00e9s a \u00e9t\u00e9 enti\u00e8rement revu : un jeu de cl\u00e9s diff\u00e9rent est utilis\u00e9 pour prot\u00e9ger les messages du handshake et les message applicatifs.<\/li>\n\n\n\n<li>Le message <code>ChangeCipherSpec<\/code>, sorte de \u00ab\u00a0cl\u00e9 de contact\u00a0\u00bb activant le mat\u00e9riel cryptographique et algorithmes n\u00e9goci\u00e9s n&rsquo;est plus utilis\u00e9.<\/li>\n\n\n\n<li>Le message <code>CertificateVerify<\/code>, auparavant uniquement utilis\u00e9 par le client lorsqu&rsquo;il doit s&rsquo;authentifier, est maintenant utilis\u00e9 par chaque partie pour s&rsquo;authentifier.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Le handshake TLSv1.2 et inf\u00e9rieur<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>handshake sans PFS<\/strong><\/h4>\n\n\n\n<p>Le handshake suit la cin\u00e9matique ci-dessous :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> |--------ClientHello------&gt;|\n |                          |\n |&lt;-------ServerHello-------|\n |&lt;-------Certificate-------|\n |&lt;-----ServerHelloDone-----|\n |                          |\n |----ClientKeyExchange----&gt;|\n |-----ChangeCipherSpec----&gt;|\n |---------Finished--------&gt;|\n |                          |\n |&lt;----ChangeCipherSpec-----|\n |&lt;--------Finished---------|\n |                          |\n |&lt;==Donn\u00e9es applicatives==&gt;|<\/code><\/pre>\n\n\n\n<p>Dans cet \u00e9change,<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le client demande l&rsquo;ouverture d&rsquo;une session TLS en envoyant un <code>ClientHello<\/code> au serveur. Ce message annonce les suites cryptographiques qu&rsquo;il supporte.<\/li>\n\n\n\n<li>Le serveur r\u00e9pond alors :\n<ul class=\"wp-block-list\">\n<li>Un <code>ServerHello<\/code> mentionnant la suite cryptographique choisie par le serveur,<\/li>\n\n\n\n<li>Un <code>Certificate<\/code>, contenant le cha\u00eene de certificats prouvant l&rsquo;identit\u00e9 du serveur,<\/li>\n\n\n\n<li>Un <code>ServerHelloDone<\/code>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Si l&rsquo;authentification est un succ\u00e8s, le client r\u00e9pond un <code>ClientKeyExchange<\/code> qui contient le <code>pre_master_secret<\/code> qu&rsquo;il a g\u00e9n\u00e9r\u00e9, chiffr\u00e9 avec la cl\u00e9 publique du serveur.<\/li>\n<\/ul>\n\n\n\n<p>Chaque cot\u00e9 a alors tout ce qu&rsquo;il faut pour d\u00e9river le materiel crytographique. Le client envoie donc :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un <code>ChangeCipherSpec<\/code> annon\u00e7ant l&rsquo;activation des m\u00e9canismes et mat\u00e9riels cryprographiques n\u00e9goci\u00e9s,<\/li>\n\n\n\n<li>Un <code>Finished<\/code> qui est un r\u00e9sum\u00e9 cryptographique sur les messages \u00e9chang\u00e9s au cours du handshake.<\/li>\n<\/ul>\n\n\n\n<p>Si la v\u00e9rification du message <code>Finished<\/code> par le serveur est satisfaisante, ce dernier envoie \u00e0 son tour un <code>ChangeCipherSpec<\/code> et un message <code>Finished<\/code>.<\/p>\n\n\n\n<p>Si la v\u00e9rification de ce dernier message par le client est concluante, l&rsquo;\u00e9change de donn\u00e9es applicatives peut commencer.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Handshake avec PFS<\/strong><\/h4>\n\n\n\n<p>Lorsque la suite cryptographique assure la PFS, le handshake suit la cin\u00e9matique ci-dessous :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> |--------ClientHello------&gt;|\n |                          |\n |&lt;-------ServerHello-------|\n |&lt;-------Certificate-------|\n |&lt;----ServerKeyExchange----|\n |&lt;-----ServerHelloDone-----|\n |                          |\n |----ClientKeyExchange----&gt;|\n |-----ChangeCipherSpec----&gt;|\n |---------Finished--------&gt;|\n |                          |\n |&lt;----ChangeCipherSpec-----|\n |&lt;--------Finished---------|\n |                          |\n |&lt;==Donn\u00e9es applicatives==&gt;|<\/code><\/pre>\n\n\n\n<p>Cet \u00e9change se produit lorsque la suite cryptographique retenue par le serveur garantit la PFS.<\/p>\n\n\n\n<p>Dans ce cas, le <code>pre_master_secret<\/code> ne sera pas g\u00e9n\u00e9r\u00e9 par le client, mais gr\u00e2ce \u00e0 un \u00e9change Diffie-Hellman.<\/p>\n\n\n\n<p>C&rsquo;est pour cela qu&rsquo;un message suppl\u00e9mentaire, <code>ServerKeyExchange<\/code>, est ici pr\u00e9sent : il contient la demi-cl\u00e9 du serveur, sign\u00e9e par sa cl\u00e9 publique.<\/p>\n\n\n\n<p>De plus, le <code>ClientKeyExchange<\/code> ne contient pas le <code>pre_master_secret<\/code> chiffr\u00e9 par la cl\u00e9 publique du serveur, mais la demi-cl\u00e9 du client.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Handshake avec authentification mutuelle<\/strong><\/h4>\n\n\n\n<p>La plupart du temps, seul le serveur s&rsquo;authentifie, mais TLS offre la possibilit\u00e9 au serveur d&rsquo;authentifier le client.<\/p>\n\n\n\n<p>Le handshake (on consid\u00e8re un handshake avec PFS mais l&rsquo;utilisation d&rsquo;un \u00e9change Diffie-Hellman n&rsquo;a rien d&rsquo;obligatoire lorsque le client s&rsquo;authentifie) ressemble alors \u00e0 ceci :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> |--------ClientHello------&gt;|\n |                          |\n |&lt;-------ServerHello-------|\n |&lt;-------Certificate-------|\n |&lt;----ServerKeyExchange----|\n |&lt;---CertificateRequest----|\n |&lt;-----ServerHelloDone-----|\n |                          |\n |----Certificate----------&gt;|\n |----ClientKeyExchange----&gt;|\n |----CertificateVerify----&gt;|\n |-----ChangeCipherSpec----&gt;|\n |---------Finished--------&gt;|\n |                          |\n |&lt;----ChangeCipherSpec-----|\n |&lt;--------Finished---------|\n |                          |\n |&lt;==Donn\u00e9es applicatives==&gt;|<\/code><\/pre>\n\n\n\n<p>L&rsquo;authentification du client se fait ainsi :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le serveur envoie un message <code>CertificateRequest<\/code> afin de demander au client de s&rsquo;authentifier. Ce message peut contenir une liste des autorit\u00e9s de certification accept\u00e9es.<\/li>\n\n\n\n<li>Le client envoie un message <code>Certificate<\/code> contenant sa cha\u00eene de certificats.<\/li>\n\n\n\n<li>Le client envoie un message <code>CertificateVerify<\/code> afin de prouver qu&rsquo;il poss\u00e8de la cl\u00e9 priv\u00e9e associ\u00e9e \u00e0 son certificat. Ce message contient donc une signature portant sur les messages de handshake \u00e9chang\u00e9s auparavant.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Le handshake TLSv1.3<\/strong><\/h2>\n\n\n\n<p>Le handshake TLSv1.3 est sensiblement diff\u00e9rent du handshake des version ant\u00e9rieures : chaque partie envoie sa demi-cl\u00e9 avant l&rsquo;authentification du serveur. Cela a pour int\u00e9r\u00eat de garantir la confidentialit\u00e9 de la suite du handshake et d&rsquo;\u00e9conomiser un aller-retour (un \u00ab\u00a0RTT\u00a0\u00bb, Round-Time-Trip).<\/p>\n\n\n\n<p>Ce sch\u00e9ma, fortement inspir\u00e9 d&rsquo;un de ceux pr\u00e9sents dans la RFC, d\u00e9crit la cin\u00e9matique d&rsquo;un handshake \u00ab\u00a0usuel\u00a0\u00bb. Pour chaque message, un <code>+<\/code> est pr\u00e9sent pour mentionner les extensions particuli\u00e8rement importantes, comme l&rsquo;extension <code>key_share<\/code> du <code>ClientHello<\/code>, qui transporte la demi-cl\u00e9 du client.<\/p>\n\n\n\n<p>Un message entour\u00e9 d&rsquo;accolades (comme <code>EncryptedExtensions<\/code>) est un message de handshake chiffr\u00e9 avec le mat\u00e9riel cryptographique du handshake.<\/p>\n\n\n\n<p>Un message entour\u00e9 de crochets (comme <code>Application Data<\/code>) est un message applicatif chiffr\u00e9 avec le mat\u00e9riel cryptographique d\u00e9di\u00e9 aux messages applicatifs.<\/p>\n\n\n\n<p>D\u00e8s que le le serveur a g\u00e9n\u00e9r\u00e9 sa demi-cl\u00e9, il est en mesure de d\u00e9river du materiel cryptographique pour prot\u00e9ger la suite du handshake.<\/p>\n\n\n\n<p>Contrairement aux version ant\u00e9rieures, le serveur ne prouve pas son identit\u00e9 en signant sa demi-cl\u00e9 : l&rsquo;authentification est assur\u00e9e par l&rsquo;envoi du <code>CertificateVerify<\/code>, prouvant la possession de la cl\u00e9 priv\u00e9e associ\u00e9e au certificat envoy\u00e9 dans le message <code>Certificate<\/code>.<\/p>\n\n\n\n<p>Chaque partie envoie un <code>Finished<\/code> r\u00e9capitulant cryptographiquement le handhsake, puis d\u00e9rive le mat\u00e9riel cryptographique applicatif.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> |-ClientHello---------------------------------->|\n |+ key_share                                    |\n |+ signature_algorithms                         |\n |                                               |\n |&lt;----------------------------------ServerHello-|\n |                                   + key_share |\n |                         {EncryptedExtensions} |\n |                                 {Certificate} |\n |                           {CertificateVerify} |\n |                                    {Finished} |\n |                                               |\n |-{Finished}----------------------------------->|\n |                                               |\n | &#91;Application Data]&lt;------->&#91;Application Data] |<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Les alertes TLS<\/strong><\/h2>\n\n\n\n<p>Les alertes sont des messages de 1 octet envoy\u00e9s lorsqu&rsquo;un probl\u00e8me survient. Une alerte peut \u00eatre fatale (la session TLS doit \u00eatre imm\u00e9diatement termin\u00e9e) ou non.<\/p>\n\n\n\n<p>Parmi les alertes les plus courantes on trouve :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>certificate_revoked - 44<\/code> ;<\/li>\n\n\n\n<li><code>certificate_expired - 45<\/code> ;<\/li>\n\n\n\n<li><code>certificate_unknown - 46<\/code> ;<\/li>\n\n\n\n<li><code>unknown_ca - 48<\/code> ;<\/li>\n\n\n\n<li><code>protocol_version - 70<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Les formats de message<\/strong><\/h2>\n\n\n\n<p>Les messages TLS poss\u00e8dent la structure suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+------+---------+--------+---------+\n| type | version | length | payload |\n+------+---------+--------+---------+<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>type<\/code> : sur 2 octets, ce champ indique si le message est un message de <code>change_cipher_spec<\/code> (<code>0x14<\/code>), d&rsquo;<code>alert<\/code> (<code>0x15<\/code>), de <code>handshake<\/code> (<code>0x16<\/code>), ou un message applicatif (<code>0x17<\/code>).<\/li>\n\n\n\n<li><code>version<\/code> : sur 2 octets, indique le num\u00e9ro de version de TLS.<\/li>\n\n\n\n<li><code>length<\/code> : sur 2 octets, indique la longueur (en octets) de la payload.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Les messages de handshake<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Avant TLSv1.3<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ClientHello<\/code><\/h4>\n\n\n\n<p>Ce message contient \u00e0 minima :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>client_version<\/code>, la version de TLS que le client souhaite utiliser ;<\/li>\n\n\n\n<li>La liste de suites cryptographiques support\u00e9es par le client, par ordre d\u00e9croissant de pr\u00e9f\u00e9rence ;<\/li>\n\n\n\n<li>La liste des algorithmes de compression support\u00e9s par le client ;<\/li>\n\n\n\n<li>Le <code>client.random<\/code>, sur 32 octets ;<\/li>\n\n\n\n<li>Un identifiant de session, not\u00e9 <code>session_id<\/code>, d&rsquo;une longueur variant entre 0 et 32 octets ;<\/li>\n\n\n\n<li>D&rsquo;\u00e9ventuelles extensions.<\/li>\n<\/ul>\n\n\n\n<p>Certaines extensions sont tr\u00e8s courantes, notamment le SNI (Server Name Indication), qui indique le nom de domaine que le client souhaite contacter.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ServerHello<\/code><\/h4>\n\n\n\n<p>Ce message contient \u00e0 minima :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>server_version<\/code>, la version de TLS choisie par le serveur ;<\/li>\n\n\n\n<li>Le <code>server.random<\/code> sur 32 octets ;<\/li>\n\n\n\n<li>Le <code>session_id<\/code> ;<\/li>\n\n\n\n<li>La suite cryptographique choisie par le serveur ;<\/li>\n\n\n\n<li>L&rsquo;algorithme de compression choisi par le serveur ;<\/li>\n\n\n\n<li>D&rsquo;\u00e9ventuelles extensions.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><code><strong>Certificate<\/strong><\/code><\/h4>\n\n\n\n<p>Ce message contient la cha\u00eene de certificats destin\u00e9es \u00e0 prouver l&rsquo;identit\u00e9 de son \u00e9metteur.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ServerKeyExchange<\/code><\/h4>\n\n\n\n<p>Ce message n&rsquo;est envoy\u00e9 que si le m\u00e9canisme d&rsquo;\u00e9change de cl\u00e9 de la suite cryptographique n\u00e9goci\u00e9 est bas\u00e9 sur un \u00e9change Diffie-Hellman.<\/p>\n\n\n\n<p>Il contient alors la demi-cl\u00e9 du serveur, sign\u00e9e \u00e0 l&rsquo;aide de sa cl\u00e9 priv\u00e9e (en fait cette signature porte aussi sur le <code>client_random<\/code> et le <code>server_random<\/code>).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>CertificateRequest<\/code><\/h4>\n\n\n\n<p>Ce message n&rsquo;est envoy\u00e9 que si le serveur exige que le client s&rsquo;authentifie. Il contient une liste (\u00e9ventuellement vide) des autorit\u00e9 de certification que le serveur souhaite que le client utilise.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ServerHelloDone<\/code><\/h4>\n\n\n\n<p>Ce message n&rsquo;a pas de contenu. Sa seule fonction est de signaler la fin des messages (<code>ServerHello + Certificate + ServerKeyExchange + CertificateRequest<\/code>) envoy\u00e9s par le serveur.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ClientKeyExchange<\/code><\/h4>\n\n\n\n<p>Ce message contient le <code>pre_master_secret<\/code> chiffr\u00e9 avec la cl\u00e9 publique du serveur lorsque le m\u00e9canisme d&rsquo;\u00e9change de cl\u00e9 de la suite cryptographique n\u00e9goci\u00e9e est RSA. Lorsque ce m\u00e9canisme est un \u00e9change Diffie-Hellman, ce message contient la demi-cl\u00e9 du client.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>CertificateVerify<\/code><\/h4>\n\n\n\n<p>Ce message, envoy\u00e9 uniquement lorsque le client doit s&rsquo;authentifier, est une signature calcul\u00e9e avec la cl\u00e9 priv\u00e9e du client sur la concat\u00e9nation des messages de handshake re\u00e7us auparavant.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ChangeCipherSpec<\/code><\/h4>\n\n\n\n<p>Ce message n&rsquo;a pas de contenu et n&rsquo;est pas un message de handshake \u00e0 proprement parler.<\/p>\n\n\n\n<p>Sa seule fonction est de signaler que son \u00e9metteur va maintenant utiliser le materiel et les m\u00e9canismes cryptographiques n\u00e9goci\u00e9s auparavant pour prot\u00e9ger ses messages ult\u00e9rieurs.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>Finished<\/code><\/h4>\n\n\n\n<p>Ce message est un r\u00e9sum\u00e9 cryptographique de l&rsquo;ensemble des messages \u00e9chang\u00e9s au cours du handshake. C&rsquo;est le premier message chiffr\u00e9 avec les cl\u00e9s et algorithmes venant d&rsquo;\u00eatre n\u00e9goci\u00e9s.<\/p>\n\n\n\n<p>L&rsquo;envoi de ce message emp\u00eache un attaquant de modifier \u00e0 son profit les messages de handhake.<\/p>\n\n\n\n<p>Son calcul a \u00e9volu\u00e9 au fil des versions :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dans SSLv3, c&rsquo;est la concat\u00e9nation de <code>MD5(master_secret + pad2 + MD5(handshake_messages + Sender + master_secret + pad1))<\/code> et <code>SHA(master_secret + pad2 + SHA(handshake_messages + Sender + master_secret + pad1));<\/code>, o\u00f9 <code>Sender<\/code> est entier de 32 bits identifiant l&rsquo;\u00e9metteur (client ou serveur) ;<\/li>\n\n\n\n<li>Dans TLSv1.0 et TLSv1.1, c&rsquo;est les 12 premiers octets de <code>PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages))<\/code> ;<\/li>\n\n\n\n<li>Dans TLSv1.2, c&rsquo;est le r\u00e9sultat de <code>PRF(master_secret, finished_label, Hash(handshake_messages))<\/code>, o\u00f9 <code>PRF<\/code> est la fonction d\u00e9crite plus bas, utilisant la fonction de hachage de la suite cryptographique n\u00e9goci\u00e9e.<\/li>\n<\/ul>\n\n\n\n<p>Que se passerait-il sans message <code>Finished<\/code> ?<\/p>\n\n\n\n<p>Le handshake aurait alors la forme suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> |--------ClientHello------&gt;|\n |                          |\n |&lt;-------ServerHello-------|\n |&lt;-------Certificate-------|\n |&lt;----ServerKeyExchange----|\n |&lt;-----ServerHelloDone-----|\n |                          |\n |----ClientKeyExchange----&gt;|\n |-----ChangeCipherSpec----&gt;|\n |                          |\n |&lt;----ChangeCipherSpec-----|<\/code><\/pre>\n\n\n\n<p>Le sc\u00e9nario suivant serait alors possible :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code> |--------ClientHello------&gt;|--------ClientHello----------&gt;|\n |                          |                              |\n |&lt;-------ServerHello-------|&lt;-------ServerHello-----------|\n |&lt;-------Certificate-------|&lt;-------Certificate-----------|\n |&lt;-----ServerHelloDone-----|&lt;-----ServerHelloDone---------|\n |                          |                              |\n |----ClientKeyExchange----&gt;|----ClientKeyExchange_bis----&gt;|\n |-----ChangeCipherSpec----&gt;|-----ChangeCipherSpec--------&gt;|\n |                          |                              |\n |&lt;----ChangeCipherSpec-----|&lt;----ChangeCipherSpec---------|\n |&lt;==Donn\u00e9es applicatives==&gt;|&lt;====Donn\u00e9es applicatives====&gt;|<\/code><\/pre>\n\n\n\n<p>L&rsquo;attaquant remplace le <code>ClientKeyExchange<\/code> envoy\u00e9 par le client par un <code>ClientKeyExchange_bis<\/code> contenant un <code>pre_master_secret_bis<\/code> choisi par l&rsquo;attaquant en position de MitM.<\/p>\n\n\n\n<p>Ensuite,<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le <code>ServerHelloDone<\/code> reste inchang\u00e9,<\/li>\n\n\n\n<li>L&rsquo;attaquant ne peut pas conna\u00eetre le <code>pre_master_secret<\/code> du client, ne peut donc pas conna\u00eetre le <code>key_block<\/code> du client, n&rsquo;est donc pas capable de d\u00e9chiffrer les messages applicatifs \u00e9mis par le client et va se contenter de les d\u00e9truire purement et simplement.<\/li>\n\n\n\n<li>L&rsquo;attaquant conna\u00eet par contre le <code>key_block<\/code> utilis\u00e9 par le serveur et est donc en mesure de lui envoyer le message de son choix.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Dans TLSv1.3<\/strong><\/h3>\n\n\n\n<p>Dans TLSv1.3, certains messages disparaissent (<code>ClientKeyExchange<\/code>, <code>ServerKeyExchange<\/code>, <code>ChangeCipherSpec<\/code>), le <code>CertificateVerify<\/code> change de r\u00f4le et l&rsquo;usage des extensions est syst\u00e9matis\u00e9.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ClientHello<\/code><\/h4>\n\n\n\n<p>Le <code>ClientHello<\/code> de TLSv1.3 est l\u00e9g\u00e8rement diff\u00e9rent, car, en plus des champs pr\u00e9sents dans les versions ant\u00e9rieures, il embarque toujours l&rsquo;extension <code>supported_versions<\/code>, qui liste les versions de TLS support\u00e9es par le client.<\/p>\n\n\n\n<p>Il embarque \u00e9galement les extensions suivantes (dans le cas d&rsquo;un handshake \u00ab\u00a0usuel\u00a0\u00bb comme sch\u00e9matis\u00e9 plus haut) :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extension <code>key_share<\/code> : cette extension est une liste de <code>KeyShareEntry<\/code>, chacun de ces \u00e9l\u00e9ments \u00e9tant un couple form\u00e9 de l&rsquo;identifiant sur deux octets d&rsquo;un groupe Diffie-Hellman et d&rsquo;une demi-cl\u00e9 calcul\u00e9 dans dans le groupe en question.<\/li>\n\n\n\n<li>Extension <code>signature_algorithms<\/code> : cette extension contient une liste d&rsquo;identifiants sur deux octets d&rsquo;un algorithme de signature qui sera utilis\u00e9 pour le calcul de la signature calcul\u00e9e dans le <code>CertificateVerify<\/code> et sur la demi-cl\u00e9 du serveur.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><code>ServerHello<\/code><\/h4>\n\n\n\n<p>Comme le <code>ClientHello<\/code>, le <code>ServerHello<\/code> de TLSv1.3 embarque obligatoirement l&rsquo;extension <code>supported_versions<\/code>.<\/p>\n\n\n\n<p>Dans le cas d&rsquo;un handshake \u00ab\u00a0usuel\u00a0\u00bb (pas d&rsquo;utilisation de PSK, etc), une extension <code>key_share<\/code> contenant une unique <code>KeyShareEntry<\/code> est pr\u00e9sente.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>Certificate<\/code><\/h4>\n\n\n\n<p>Ce message contient la cha\u00eene de certification de l&rsquo;\u00e9metteur, comme dans les versions pr\u00e9c\u00e9dentes.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>CertificateVerify<\/code><\/h4>\n\n\n\n<p>Ce message est une signature calcul\u00e9e avec la cl\u00e9 priv\u00e9e de l&rsquo;\u00e9metteur et portant sur un hach\u00e9 (le <em>Transcript-Hash<\/em>) de la concat\u00e9nation des messages de handshake ant\u00e9rieures et du message <code>Certificate<\/code> de l&rsquo;\u00e9metteur.<\/p>\n\n\n\n<p>Dans TLSv1.3, c&rsquo;est ce message qui authentifie son \u00e9metteur.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>Finished<\/code><\/h4>\n\n\n\n<p>Le message <code>Finished<\/code> de TLSv1.3 a le m\u00eame r\u00f4le de r\u00e9sum\u00e9 cryptographique du handshake que dans les versions ant\u00e9rieures, mais son calcul diff\u00e8re : c&rsquo;est un HMAC calcul\u00e9 sur le <em>Transcript-Hash<\/em> (encore lui) de la concat\u00e9nation des message de handshake, du <code>Certificate<\/code> et du <code>CertificateVerify<\/code> de l&rsquo;\u00e9metteur.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Les suites cryptographiques<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Avant TLSv1.3<\/strong><\/h3>\n\n\n\n<p>Jusqu&rsquo;\u00e0 TLSv1.2, une suite de chiffrement est un quadruplet sp\u00e9cifiant :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un m\u00e9canisme de Key Exchange,<\/li>\n\n\n\n<li>L&rsquo;algorithme \u00e0 cl\u00e9 publique utilis\u00e9 par le serveur,<\/li>\n\n\n\n<li>Un algorithme de chiffrement symetrique,<\/li>\n\n\n\n<li>La fonction de hachage utilis\u00e9e par le HMAC.<\/li>\n<\/ul>\n\n\n\n<p>Exemples :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>TLS_NULL_WITH_NULL_NULL<\/code> : la suite qui ne fait rien.<\/li>\n\n\n\n<li><code>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA<\/code> : suite export utilisant une cl\u00e9 RSA de 512 bits, DES en mode CBC avec une cl\u00e9 de 40 bits et SHA-1 comme fonction de hachage.<\/li>\n\n\n\n<li><code>SSL_RSA_WITH_DES_CBC_SHA<\/code> : la m\u00eame suite en version non-export.<\/li>\n\n\n\n<li><code>SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA<\/code> : authentification avec RSA, \u00e9change de cl\u00e9 avec Diffie-Hellman statique, chiffrement avec 3DES en mode CBC, SHA-1 comme fonction de hachage.<\/li>\n\n\n\n<li><code>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA<\/code> : pas d&rsquo;authentification, \u00e9change de cl\u00e9 avec Diffie-Hellman anonyme, chiffrement avec 3DES en mode CBC, SHA-1 comme fonction de hachage.<\/li>\n\n\n\n<li><code>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA<\/code> : authentification avec RSA, \u00e9change de cl\u00e9 avec Diffie-Hellman \u00e9ph\u00e9m\u00e8re, chiffrement avec 3DES en mode CBC, SHA-1 comme fonction de hachage.<\/li>\n\n\n\n<li><code>TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA<\/code> : la m\u00eame suite, renomm\u00e9e dans TLSv1.0.<\/li>\n\n\n\n<li><code>TLS_RSA_WITH_AES_256_CBC_SHA256<\/code> : authentification et \u00e9change de cl\u00e9 avec RSA, chiffrement avec AES en mode CBC, SHA256 comme fonction de hachage.<\/li>\n\n\n\n<li><code>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256<\/code> : authentification avec RSA, \u00e9change de cl\u00e9 avec Diffie-Hellman \u00e9ph\u00e9m\u00e8re, chiffrement avec AES en mode CBC, SHA256 comme fonction de hachage.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Dans TLSv1.3<\/strong><\/h3>\n\n\n\n<p>Seul cinq suites cryptographiques existent dans TLSv1.3. Contrairement aux versions ant\u00e9rieures du protocole, ces suites sp\u00e9cifient uniquement l&rsquo;algorithme de chiffrement et le m\u00e9canisme d&rsquo;integrit\u00e9.<\/p>\n\n\n\n<p>Ces suites sont :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>TLS_AES_128_GCM_SHA256 (0x1301)<\/code> ;<\/li>\n\n\n\n<li><code>TLS_AES_256_GCM_SHA384 (0x1302)<\/code> ;<\/li>\n\n\n\n<li><code>TLS_CHACHA20_POLY1305_SHA256 (0x1303)<\/code> ;<\/li>\n\n\n\n<li><code>TLS_AES_128_CCM_SHA256 (0x1304)<\/code> ;<\/li>\n\n\n\n<li><code>TLS_AES_128_CCM_8_SHA256 (0x1305)<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Le mode GCM (Galois Counter Mode) est un mode authentifiant : les donn\u00e9es sont chiffr\u00e9es avec le mode CTR (chaque bloc est xor\u00e9 avec un compteur chiffr\u00e9, le compteur \u00e9tant incr\u00e9ment\u00e9 \u00e0 chaque bloc) et un MAC est calcul\u00e9 en r\u00e9alisant des xor et des multiplications dans le corps fini GF(2^128) sur les blocs chiffr\u00e9s.<\/p>\n\n\n\n<p>Le mode CCM (Counter mode with Cbc-Mac) est un autre mode authentifiant. Il utilise \u00e9galement le mode CTR pour le chiffrement, mais le calcul du MAC est r\u00e9alis\u00e9 avec un algorithme apparent\u00e9 \u00e0 CBC-MAC.<\/p>\n\n\n\n<p>La fonction de hachage mentionn\u00e9e est la fonction de hachage utilis\u00e9e par la fonction de d\u00e9rivation de cl\u00e9 (HKDF) et lors du calcul du <code>Transcript-Hash<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading alignwide\"><strong>D\u00e9rivation du mat\u00e9riel cryptographique de session<\/strong><\/h2>\n\n\n\n<h4 class=\"wp-block-heading alignwide\"><strong>Avant TLSv1.3<\/strong><\/h4>\n\n\n\n<p>Les versions de TLS ant\u00e9rieures \u00e0 TLSv1.3 d\u00e9rivent le mat\u00e9riel cryptographique \u00e0 partir du <code>master_secret<\/code> en utilisant une <em>PseudoRandomFunction<\/em> construite \u00e0 partir de fonctions de HMAC.<\/p>\n\n\n\n<p>On commence par consid\u00e9rer la fonction de HMAC associ\u00e9e \u00e0 la fonction de hachage <code>hash<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>HMAC_hash(secret, message);<\/code><\/pre>\n\n\n\n<p>\u00c0 partir de cette fonction, on construit une fonction <code>P_hash<\/code> \u00ab\u00a0\u00e9tirant\u00a0\u00bb une <code>seed<\/code> \u00e0 l&rsquo;aide d&rsquo;un <code>secret<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +\n                              HMAC_hash(secret, A(2) + seed) +\n                              HMAC_hash(secret, A(3) + seed) + ...<\/code><\/pre>\n\n\n\n<p>La suite <code>A()<\/code> \u00e9tant d\u00e9finie par r\u00e9currence :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>A(0) = seed<\/code><\/li>\n\n\n\n<li><code>A(i) = HMAC_hash(secret, A(i-1))<\/code><\/li>\n<\/ul>\n\n\n\n<p>Avant TLSv1.2, la fonction <code>PRF<\/code> combine <code>P_MD5<\/code> et <code>P_SHA-1<\/code> via un xor :`<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR\n                                  P_SHA-1(S2, label + seed);<\/code><\/pre>\n\n\n\n<p>Dans TLSv1.2, seule la fonction de hachage SHA-256 est utilis\u00e9e :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>PRF(secret, label, seed) = P_&lt;hash&gt;(secret, label + seed)<\/code><\/pre>\n\n\n\n<p>Dans tous les cas, la fonction <code>PRF<\/code> ainsi d\u00e9finie est utilis\u00e9e comme ci-dessous pour d\u00e9river le mat\u00e9riel cryptographique \u00e0 partir :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Du <code>master_secret<\/code>, calcul\u00e9 \u00e0 partir du secret commun,<\/li>\n\n\n\n<li>Du <code>server_random<\/code> que serveur envoie dans son <code>ServerHello<\/code>,<\/li>\n\n\n\n<li>Du <code>client_random<\/code> que le client envoie dans son <code>ClientHello<\/code>.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>key_block = PRF(SecurityParameters.master_secret,\n                \"key expansion\",\n                SecurityParameters.server_random +\n                SecurityParameters.client_random);<\/code><\/pre>\n\n\n\n<p>Le <code>master_secret<\/code> est lui-m\u00eame d\u00e9riv\u00e9 \u00e0 partir du secret commun, le <code>pre_master_secret<\/code>, en utilisant <code>PRF<\/code> \u00e9galement :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>master_secret = PRF(pre_master_secret, \"master secret\",\n           ClientHello.random + ServerHello.random)&#91;0..47];<\/code><\/pre>\n\n\n\n<p>Le <code>pre_master_secret<\/code> est :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>G\u00e9n\u00e9r\u00e9 par le client et envoy\u00e9 chiffr\u00e9 avec la cl\u00e9 publique du serveur dans le message ClientKeyExchange,<\/li>\n\n\n\n<li>ou bien g\u00e9n\u00e9r\u00e9 \u00e0 partir via un \u00e9change Diffie-Hellman. Dans ce cas,\n<ul class=\"wp-block-list\">\n<li>le client envoie son <code>g^a mod p<\/code> dans un <code>ClientKeyExchange<\/code>,<\/li>\n\n\n\n<li>le serveur envoie son <code>g^b mod p<\/code> sign\u00e9 avec sa cl\u00e9 priv\u00e9e dans un <code>ServerKeyExchange<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Dans ce dernier cas, le <code>pre_master_secret<\/code> est le r\u00e9sultat de cet \u00e9change Diffie-Hellman.<\/p>\n\n\n\n<p>L&rsquo;utilisation du <code>key_block<\/code> varie selon les versions et les algorithmes de chiffrement :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dans SSLv3.0 et TLSv1.0, il est d\u00e9coup\u00e9 en <code>client_write_MAC_secret<\/code>, <code>server_write_MAC_secret<\/code> (cl\u00e9s utilis\u00e9es pour les calculs de HMAC), <code>client_write_key<\/code>, <code>server_write_key<\/code> (cl\u00e9s utilis\u00e9es pour le chiffrement), <code>client_write_IV<\/code> et <code>server_write_IV<\/code> (vecteurs d&rsquo;initialisation pour le chiffrement du premier message lorsque le mode CBC est utilis\u00e9).<\/li>\n\n\n\n<li>Dans TLSv1.1 et TLSv1.2, pour contrer l&rsquo;attaque BEAST les vecteurs d&rsquo;initialisation sont explicites et se situent au d\u00e9but des messages applicatifs. Un vecteur d&rsquo;initialisation est cependant extrait du <code>key_block<\/code> pour initialiser le <code>nonce<\/code> si un m\u00e9canisme AEAD (comme AES-GCM) est utilis\u00e9.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading alignwide\"><strong>Dans TLSv1.3<\/strong><\/h4>\n\n\n\n<p>La d\u00e9rivation de cl\u00e9 a \u00e9t\u00e9 enti\u00e8rement repens\u00e9e dans TLSv1.3. Elle utilise deux fonctions, <code>HKDF-Extract<\/code> et <code>HKDF-Expand<\/code>, d\u00e9finies dans la RFC 5869.<\/p>\n\n\n\n<p>Le sch\u00e9ma de d\u00e9rivation de cl\u00e9s de TLSv1.3 introduit une s\u00e9paration entre cl\u00e9s prot\u00e9geant le handshake et cl\u00e9s prot\u00e9geant le trafic applicatif : une compromission des cl\u00e9s de handshake n&rsquo;aura pas d&rsquo;impact sur les cl\u00e9s applicatives.<\/p>\n\n\n\n<p>La fonction <code>HKDF-Extract<\/code> se r\u00e9duit \u00e0 un appel \u00e0 une fonction de HMAC : <code>HKDF-Extract(salt, IKM) = HMAC-Hash(salt, IKM)<\/code>,<\/p>\n\n\n\n<p>La fonction <code>HKDF-Expand<\/code> utilise une cl\u00e9 secr\u00e8te <code>PRK<\/code>, une cha\u00eene de caract\u00e8re <code>info<\/code> qui fait office de label et un entier <code>L<\/code> sp\u00e9cifiant le nombre d&rsquo;octets \u00e0 produire.<\/p>\n\n\n\n<p>Le calcul de <code>OKM = HKDF-Expand(PRK, info, L)<\/code> est bas\u00e9 sur la construction par r\u00e9currence d&rsquo;une cha\u00eene <code>T<\/code> :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>T(0)<\/code> est la cha\u00eene vide,`<\/li>\n\n\n\n<li><code>T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)<\/code>,<\/li>\n\n\n\n<li><code>T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)<\/code>,<\/li>\n\n\n\n<li><code>T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)<\/code>,<\/li>\n<\/ul>\n\n\n\n<p>et ainsi de suite et <code>T = T(1) | T(2) | T(3) | ... | T(N)<\/code>, o\u00f9 <code>N = 1 + (L\/HashLen)<\/code>.<\/p>\n\n\n\n<p>Finalement, <code>OKM<\/code> est \u00e9gal aux <code>L<\/code> premiers octets de <code>T<\/code>.<\/p>\n\n\n\n<p>La RFC 8446 d\u00e9crivant TLSv1.3 d\u00e9finit une fonction <code>HKDF-Expand-Label<\/code> \u00e0 partir de <code>HKDF-Expand<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HKDF-Expand-Label(Secret, Label, Context, Length) =\n            HKDF-Expand(Secret, HkdfLabel, Length)<\/code><\/pre>\n\n\n\n<p>O\u00f9 <code>HkdfLabel<\/code> est la concat\u00e9nation de la cha\u00eene de caract\u00e8res <code>\"tls13 \" + Label + Context<\/code> et de la longueur de cette cha\u00eene.<\/p>\n\n\n\n<p>Ainsi qu&rsquo;une fonction <code>Derive-Secret<\/code>, construite \u00e0 partir de <code>HKDF-Expand-Label<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Derive-Secret(Secret, Label, Messages) =\n            HKDF-Expand-Label(Secret, Label,\n            Transcript-Hash(Messages), Hash.length)<\/code><\/pre>\n\n\n\n<p>La d\u00e9rivation des cl\u00e9s dans TLSv1.3 est enti\u00e8rement r\u00e9capitul\u00e9e par la figure pr\u00e9sente au paragraphe 7.1 de la RFC 8446 :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>             0\n             |\n             v\n   PSK -&gt;  HKDF-Extract = Early Secret\n             |\n             +-----&gt; Derive-Secret(., \"ext binder\" | \"res binder\", \"\")\n             |                     = binder_key\n             |\n             +-----&gt; Derive-Secret(., \"c e traffic\", ClientHello)\n             |                     = client_early_traffic_secret\n             |\n             +-----&gt; Derive-Secret(., \"e exp master\", ClientHello)\n             |                     = early_exporter_master_secret\n             v\n       Derive-Secret(., \"derived\", \"\")\n             |\n             v\n   (EC)DHE -&gt; HKDF-Extract = Handshake Secret\n             |\n             +-----&gt; Derive-Secret(., \"c hs traffic\",\n             |                     ClientHello...ServerHello)\n             |                     = client_handshake_traffic_secret\n             |\n             +-----&gt; Derive-Secret(., \"s hs traffic\",\n             |                     ClientHello...ServerHello)\n             |                     = server_handshake_traffic_secret\n             v\n       Derive-Secret(., \"derived\", \"\")\n             |\n             v\n   0 -&gt; HKDF-Extract = Master Secret\n             |\n             +-----&gt; Derive-Secret(., \"c ap traffic\",\n             |                     ClientHello...server Finished)\n             |                     = client_application_traffic_secret_0\n             |\n             +-----&gt; Derive-Secret(., \"s ap traffic\",\n             |                     ClientHello...server Finished)\n             |                     = server_application_traffic_secret_0\n             |\n             +-----&gt; Derive-Secret(., \"exp master\",\n             |                     ClientHello...server Finished)\n             |                     = exporter_master_secret\n             |\n             +-----&gt; Derive-Secret(., \"res master\",\n                                   ClientHello...client Finished)\n                                   = resumption_master_secret<\/code><\/pre>\n\n\n\n<p>Dans le cas d&rsquo;un handshake \u00ab\u00a0usuel\u00a0\u00bb, le secret commun issu de l&rsquo;\u00e9change Diffie-Hellman est d\u00e9riv\u00e9 en un <code>Handshake Secret<\/code> avec un appel \u00e0 <code>HKDF-Extract<\/code>.<\/p>\n\n\n\n<p>Cette valeur est d\u00e9riv\u00e9e, \u00e0 l&rsquo;aide de <code>Derive-Secret<\/code>, en une valeur diff\u00e9rente pour le client (<code>client_handshake_traffic_secret<\/code>) et pour le serveur (<code>server_handshake_traffic_secret<\/code>), valeur qui sera par la suite utilis\u00e9e pour la d\u00e9rivation des cl\u00e9s qui seront employ\u00e9es pour prot\u00e9ger les messages de handhake, selon la relation<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>&#91;sender]_write_key = HKDF-Expand-Label(Secret, \"key\", \"\", key_length)\n&#91;sender]_write_iv  = HKDF-Expand-Label(Secret, \"iv\", \"\", iv_length)<\/code><\/pre>\n\n\n\n<p><code>[sender]_write_key<\/code> et <code>[sender]_write_iv<\/code> sont utilis\u00e9es comme secret et nonce par le chiffrement AEAD.<\/p>\n\n\n\n<p>Une seconde d\u00e9rivation est r\u00e9alis\u00e9e pour prot\u00e9ger les messages applicatifs : le <code>Handshake Secret<\/code> est d\u00e9riv\u00e9 en un <code>Master Secret<\/code> moyennant un appel \u00e0 <code>Derive-Secret<\/code> puis <code>HKDF-Extract<\/code>.<\/p>\n\n\n\n<p>Ce <code>Master Secret<\/code> est ensuite d\u00e9riv\u00e9 en un <code>client_application_traffic_secret_0<\/code> ou <code>server_application_traffic_secret_0<\/code> suivant le c\u00f4t\u00e9 de la connexion, secret \u00e0 son tour employ\u00e9 pour d\u00e9river une cl\u00e9 de chiffrement et un vecteur d&rsquo;initialisation, selon la relation ci-dessus.<\/p>\n\n\n\n<h2 class=\"wp-block-heading alignwide\"><strong>Le chiffrement des messages applicatifs<\/strong><\/h2>\n\n\n\n<h4 class=\"wp-block-heading alignwide\"><strong>Cas des chiffrements par flot<\/strong><\/h4>\n\n\n\n<p>Si le m\u00e9canisme de chiffrement est un algorithme de chiffrement par flot (RC4, typiquement), alors un message chiffr\u00e9 est obtenu en chiffrant ceci :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+---------------+------+\n| message clair | HMAC |\n+---------------+------+<\/code><\/pre>\n\n\n\n<p>Le <code>HMAC<\/code> est d\u00e9fini par la formule :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +\n                     TLSCompressed.version + TLSCompressed.length +\n                     TLSCompressed.fragment));<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>MAC_write_secret<\/code> est la cl\u00e9 de calcul de HMAC extraite de <code>key_block<\/code> ;<\/li>\n\n\n\n<li><code>seq_num<\/code> est un num\u00e9ro de s\u00e9quence sur 64 bits destin\u00e9 \u00e0 emp\u00eacher le rejeu et incr\u00e9ment\u00e9 \u00e0 chaque message. Il vaut initialement z\u00e9ro.<\/li>\n\n\n\n<li><code>TLSCompressed.type<\/code> est le type du message clair,<\/li>\n\n\n\n<li><code>TLSCompressed.version<\/code> est la version de TLS utilis\u00e9e,<\/li>\n\n\n\n<li><code>TLSCompressed.length<\/code> est la taille du message clair apr\u00e8s \u00e9ventuelle compression,<\/li>\n\n\n\n<li><code>TLSCompressed.fragment<\/code> est le message en clair, \u00e9ventuellement compress\u00e9.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading alignwide\"><strong>Cas des chiffrements par bloc en mode CBC<\/strong><\/h4>\n\n\n\n<p>Si le m\u00e9canisme de chiffrement est un algorithme de chiffrement par bloc et que le mode op\u00e9ratoire est CBC, un message chiffr\u00e9 est obtenu en chiffrant ceci :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+---------------+------+---------+\n| message clair | HMAC | padding |\n+---------------+------+---------+<\/code><\/pre>\n\n\n\n<p>Le message chiffr\u00e9 envoy\u00e9 <code>C<\/code> et le message clair <code>M<\/code> sont donc reli\u00e9s par la relation <code>C = E(M, HMAC, Padding)<\/code>.<\/p>\n\n\n\n<p>La longueur du padding est telle que le bloc (<code>message clair + hmac + padding<\/code>) a une taille multiple de la taille de bloc de l&rsquo;algorithme de chiffrement.<\/p>\n\n\n\n<p>\u00c0 partir de TLSv1.0, chaque octet de padding a une valeur \u00e9gale \u00e0 cette longueur (ainsi le padding peut \u00eatre <code>0x01<\/code>, ou bien <code>0x0202<\/code>, ou bien <code>0x030303<\/code>, etc). Dans SSLv3, seul le dernier octet de padding doit avoir une valeur \u00e9gale \u00e0 la longueur du padding.<\/p>\n\n\n\n<p>Le <code>HMAC<\/code> est calcul\u00e9 de la m\u00eame mani\u00e8re que dans le cas d&rsquo;un chiffrement par flot.<\/p>\n\n\n\n<p>En r\u00e9ponse \u00e0 certaines attaques (BEAST notamment), la gestion du vecteur d&rsquo;initialisation (<code>IV<\/code>) a \u00e9t\u00e9 modifi\u00e9e dans le mode CBC \u00e0 partir de TLSv1.1.<\/p>\n\n\n\n<p>Avant TLSv1.1, le premier message \u00e9tait chiffr\u00e9 avec un <code>IV<\/code> calcul\u00e9 lors de la d\u00e9rivation du <code>master_secret<\/code> en <code>key_block<\/code> et les messages suivants utilisaient comme <code>IV<\/code> le dernier bloc du message chiffr\u00e9 pr\u00e9c\u00e9dent.<\/p>\n\n\n\n<p>\u00c0 partir de TLSv1.1, l&rsquo;<code>IV<\/code> est explicitement mentionn\u00e9 dans le message. Le message chiffr\u00e9 est calcul\u00e9 comme auparavant, mais commence maintenant par l&rsquo;<code>IV<\/code> et l&rsquo;on a donc la relation :<\/p>\n\n\n\n<p><code>C = IV + E(M, HMAC, Padding)<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading alignwide\"><strong>Mac-Then-Encrypt ou Encrypt-Then-Mac ?<\/strong><\/h4>\n\n\n\n<p>\u00c0 l&rsquo;origine, TLS utilise Mac-Then-Encrypt, il concat\u00e8ne le MAC du message clair \u00e0 la fin de ce dernier, ajoute du padding et chiffre le tout.<\/p>\n\n\n\n<p>Plusieurs travaux th\u00e9oriques (https:\/\/link.springer.com\/content\/pdf\/10.1007\/3-540-44448-3_41.pdf et https:\/\/eprint.iacr.org\/2002\/078.pdf) ont montr\u00e9 que le mode Encrypt-Then-Mac (on chiffre le message clair, on calcule le MAC du message chiffr\u00e9 r\u00e9sultant et on concat\u00e8ne ce MAC \u00e0 la fin du message chiffr\u00e9) est pr\u00e9f\u00e9rable.<\/p>\n\n\n\n<p>De plus, le mode Mac-Then-Encrypt de SSL\/TLS offre un contexte favorable pour un oracle de padding, la v\u00e9rification du padding \u00e9tant r\u00e9alis\u00e9e avant la v\u00e9rification du MAC.<\/p>\n\n\n\n<p>Avant TLSv1.1, le code d&rsquo;alerte n&rsquo;\u00e9tait pas le m\u00eame en cas de padding incorrect (<code>decryption_failed<\/code>) et en cas de MAC (<code>bad_record_mac<\/code>), fournissant ainsi un oracle de padding.<\/p>\n\n\n\n<p>La RFC 7366, publi\u00e9e en 2014, d\u00e9crit une extension permettant de n\u00e9gocier l&rsquo;utilisation du mode Encrypt-Then-Mac : si le client souhaite utiliser ETM, il ajoute l&rsquo;extension <code>encrypt-then-mac<\/code> \u00e0 son <code>ClientHello<\/code>.<\/p>\n\n\n\n<p>Si le serveur est d&rsquo;accord, il ajoute l&rsquo;extension <code>encrypt-then-mac<\/code> \u00e0 son <code>ServerHello<\/code>.<\/p>\n\n\n\n<p>Lorsque cette extension est utilis\u00e9e,<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le message chiffr\u00e9 <code>C<\/code> est calcul\u00e9 via <code>C = E(M + padding)<\/code> en cas d&rsquo;usage de TLSv1.0 o\u00f9 l&rsquo;<code>IV<\/code> est implicite, ou <code>C = IV + E(M + padding)<\/code> pour TLSv1.1 et TLSv1.2 o\u00f9 l&rsquo;<code>IV<\/code> est explicite ;<\/li>\n\n\n\n<li>Le calcul du MAC est relativement similaire \u00e0 celui r\u00e9alis\u00e9 dans le cas historique : <code>MAC = HMAC_hash(MAC_write_secret + seq_num + type + version + length + C)<\/code>.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading alignwide\"><strong>Cas des chiffrements authentifiants (mode AEAD) dans TLSv1.2<\/strong><\/h4>\n\n\n\n<p>TLSv1.2 introduit l&rsquo;utilisant de mode authentifiant comme GCM ou CCM (on parle de mode AEAD, Authenticated Encryption with Associated Data).<\/p>\n\n\n\n<p>Un message chiffr\u00e9 <code>C<\/code> est calcul\u00e9 \u00e0 partir du message clair <code>M<\/code> via la relation <code>C = nonce_explicit + AEAD(M)<\/code>. Concr\u00e8tement, AEAD est ici AES en mode GCM ou CCM.<\/p>\n\n\n\n<p>AEAD prend en param\u00e8tre :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le message clair <code>M<\/code>,<\/li>\n\n\n\n<li>Le <code>nonce<\/code>, qui est la concat\u00e9nation d&rsquo;un vecteur d&rsquo;initialisation <code>IV<\/code> extrait de <code>key_block<\/code> et de la partie \u00ab\u00a0explicite\u00a0\u00bb <code>nonce_explicit<\/code> : <code>nonce = IV + nonce_explicit<\/code>,<\/li>\n\n\n\n<li>les donn\u00e9es additionnelles qui sont la concat\u00e9nation du num\u00e9ro de s\u00e9quence <code>seq_num<\/code> \u00e9voqu\u00e9 plus haut, du type du message, de la version de TLS et de la taille du message clair.<\/li>\n<\/ul>\n\n\n\n<p>Le r\u00e9sultat <code>AEAD(M)<\/code> contient un tag authentifiant dans son dernier bloc.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Chiffrement en mode AEAD dans TLSv1.3<\/strong><\/h4>\n\n\n\n<p>TLSv1.3 utilise exclusivement des modes authentifiants et effectue le chiffrement diff\u00e9remment de TLSv1.2 :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le <code>nonce<\/code> est maintenant compl\u00e8tement implicite et est d\u00e9fini comme \u00e9tant le xor du vecteur d&rsquo;initialisation provenant de la d\u00e9rivation de cl\u00e9s et du <code>seq_num<\/code>.<\/li>\n\n\n\n<li>Le bloc <code>additional_data<\/code> est quasi-identique \u00e0 celui de TLSv1.2, la seule diff\u00e9rence \u00e9tant qu&rsquo;il ne contient plus <code>seq_num<\/code>, si bien que <code>C = AEAD(M)<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Les m\u00e9canismes de reprises de session<\/strong><\/h2>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Le <code>session_id<\/code><\/strong><\/h4>\n\n\n\n<p>Lors d&rsquo;un handshake \u00ab\u00a0normal\u00a0\u00bb, le serveur transmet via son <code>ServerHello<\/code> un identifiant de session, le <code>session_id<\/code>.<\/p>\n\n\n\n<p>Cet identifiant peut \u00eatre utilis\u00e9 pour reprendre une session ant\u00e9rieure : le client inclut ce <code>session_id<\/code> dans son <code>ClientHello<\/code>.<\/p>\n\n\n\n<p>Si ce <code>session_id<\/code> est connu du serveur, alors le mat\u00e9riel cryptographique n\u00e9goci\u00e9 lors du handshake initial est directement r\u00e9utilis\u00e9, sans nouvelle authentification du serveur ni n\u00e9gociation du <code>pre_master_secret<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Client                                                Server\n\nClientHello                   --------&gt;\n                                                 ServerHello\n                                          &#91;ChangeCipherSpec]\n                              &lt;--------             Finished\n&#91;ChangeCipherSpec]\nFinished                      --------&gt;\nApplication Data              &lt;-------&gt;     Application Data<\/code><\/pre>\n\n\n\n<p>Le <code>session_id<\/code> ne contient aucun secret en soi (comme il est \u00e9chang\u00e9 au tout d\u00e9but du handshake il est de toute fa\u00e7on public !) et est juste un index auquel client et serveur associent une sauvegarde les cl\u00e9s de la session en question.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Les tickets de session<\/strong><\/h4>\n\n\n\n<p>Le m\u00e9canisme \u00e0 base de <code>session_id<\/code> a deux inconv\u00e9nients :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>La RFC d\u00e9conseille de sauvegarder les sessions plus de 24 heures. Il n&rsquo;est donc pas appropri\u00e9 pour le maintien d&rsquo;une session \u00e0 long terme.<\/li>\n\n\n\n<li>Le serveur doit conserver le mat\u00e9riel cryptographique associ\u00e9 \u00e0 la session, ce qui est p\u00e9nalisant si le serveur a des ressources limit\u00e9es, ou interagit avec un grand nombre de clients.<\/li>\n<\/ul>\n\n\n\n<p>Le m\u00e9canisme de ticket de session d\u00e9crit dans la RFC 4507, puis 5077, d\u00e9crit comment d\u00e9porter dans le client le stockage des \u00e9l\u00e9ments de session.<\/p>\n\n\n\n<p>En premier lieu, le client doit demander un ticket de session au serveur, chose qu&rsquo;il fait en incorporant une extension <code>SessionTicket<\/code> dans son <code>ClientHello<\/code>. Si le serveur supporte ce m\u00e9canisme, il le signale en incorporant \u00e9galement un <code>SessionTicket<\/code> dans son <code>ServerHello<\/code>, puis envoie un message <code>NewSessionTicket<\/code> avant son <code>ChangeCipherSpec<\/code>.<\/p>\n\n\n\n<p>Cette cin\u00e9matique est r\u00e9capitul\u00e9e par ce sch\u00e9ma issu de la RFC 5077 :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>Client                                               Server\n\nClientHello\n(empty SessionTicket extension)--------&gt;\n                                                ServerHello\n                            (empty SessionTicket extension)\n                                               Certificate*\n                                         ServerKeyExchange*\n                                        CertificateRequest*\n                             &lt;--------      ServerHelloDone\nCertificate*\nClientKeyExchange\nCertificateVerify*\n&#91;ChangeCipherSpec]\nFinished                     --------&gt;\n                                           NewSessionTicket\n                                         &#91;ChangeCipherSpec]\n                             &lt;--------             Finished\nApplication Data             &lt;-------&gt;     Application Data<\/code><\/pre>\n\n\n\n<p>S&rsquo;il souhaite reprendre la session initiale, le client dans son <code>ClientHello<\/code> une extension <code>SessionTicket<\/code> contenant le <code>SessionTicket<\/code> envoy\u00e9 par le serveur.<\/p>\n\n\n\n<p>Le mat\u00e9riel cryptographique pr\u00e9c\u00e9dent est r\u00e9utilis\u00e9 sans authentification du serveur ni \u00e9change de cl\u00e9 et le serveur renouvelle son ticket de session :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>Client                                                Server\nClientHello\n(SessionTicket extension)      --------&gt;\n                                                 ServerHello\n                             (empty SessionTicket extension)\n                                            NewSessionTicket\n                                          &#91;ChangeCipherSpec]\n                              &lt;--------             Finished\n&#91;ChangeCipherSpec]\nFinished                      --------&gt;\nApplication Data              &lt;-------&gt;     Application Data<\/code><\/pre>\n\n\n\n<p>Le ticket de session est une sauvegarde de l&rsquo;\u00e9tat de la session (suite de chiffrement, <code>master_secret<\/code>, etc) chiffr\u00e9e avec une cl\u00e9 sym\u00e9trique uniquement connue du serveur : sans cela, un attaquant interceptant ce ticket pourrait totalement compromettre la session.<\/p>\n\n\n\n<p>Les informations pr\u00e9sentes dans le ticket de session sont donc uniquement destin\u00e9es au serveur : le client doit stocker le <code>master_secret<\/code> et autres \u00e9l\u00e9ments de l&rsquo;\u00e9tat de la session \u00ab\u00a0\u00e0 cot\u00e9\u00a0\u00bb du ticket de session.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>La reprise de session dans TLSv1.3<\/strong><\/h3>\n\n\n\n<p>Dans TLSv1.3, les m\u00e9canismes \u00e0 base de <code>session_id<\/code> et de ticket de session sont obsol\u00e8tes et la reprise de session utilise les m\u00e9canismes de PSK propres \u00e0 cette version.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Vuln\u00e9rabilit\u00e9s dans TLS<\/strong><\/h2>\n\n\n\n<p>La suite du document est une liste &#8211; forc\u00e9ment non exhaustive &#8211; de vuln\u00e9rabilit\u00e9s int\u00e9ressantes ayant affect\u00e9es SSL\/TLS.<\/p>\n\n\n\n<p>Ces vuln\u00e9rabilit\u00e9s peuvent \u00eatre<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>dues aux algorithmes cryptographiques employ\u00e9s par SSL\/TLS,<\/li>\n\n\n\n<li>inh\u00e9rentes au protocole SSL\/TLS,<\/li>\n\n\n\n<li>caus\u00e9es par des erreurs d&rsquo;impl\u00e9mentation.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading alignwide\"><strong>Les vuln\u00e9rabilit\u00e9s cryptographiques<\/strong><\/h3>\n\n\n\n<p>Ces vuln\u00e9rabilit\u00e9s peuvent \u00eatre du fait des algorithmes employ\u00e9s par TLS, ou \u00eatre caus\u00e9s par la mani\u00e8re dont TLS les utilise.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Oracle de padding dans RSA<\/strong><\/h4>\n\n\n\n<p>L&rsquo;attaque par oracle de padding a \u00e9t\u00e9 publi\u00e9e en 1998 par Daniel Bleichenbacher dans un article nomm\u00e9 \u00ab\u00a0Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS#1\u00a0\u00bb.<\/p>\n\n\n\n<p>Les trois principaux ingr\u00e9dients de cette attaque sont :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>le fait que la fonction RSA est homomorphe : <code>RSA(xy) mod n = xy^e mod n = (x^e mod n) * (y^e mod n) = RSA(x) * RSA(y) mod n<\/code>.<\/li>\n\n\n\n<li>la mani\u00e8re dont est padd\u00e9e un bloc de donn\u00e9e chiffr\u00e9 avec RSA.<\/li>\n\n\n\n<li>la pr\u00e9sence d&rsquo;un oracle de padding dans le m\u00e9canisme de d\u00e9chiffrement : ce m\u00e9canisme se comporte diff\u00e9remment selon que le padding du message d\u00e9chiffr\u00e9 soit valide ou non.<\/li>\n<\/ul>\n\n\n\n<p>Dans SSLv3, le <code>pre_master_secret<\/code> est chiffr\u00e9 selon la version 1.5 du standard PKCS#1.<\/p>\n\n\n\n<p>Ce standard d\u00e9crit comment une <code>payload<\/code> doit \u00eatre padd\u00e9e avant d&rsquo;\u00eatre chiffr\u00e9e avec une cl\u00e9 publique RSA :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+----+----+---------+----+---------+\n| 00 | 02 | padding | 00 | payload |\n+----+----+---------+----+---------+\n&lt;------------ 8*k bits ------------&gt;<\/code><\/pre>\n\n\n\n<p>Les deux octets de poids fort doivent donc \u00eatre <code>0x00<\/code> et <code>0x02<\/code>.<\/p>\n\n\n\n<p>Du fait de cette structure, le message <\/p>\n\n\n\n<p><code>m = 0x02 + padding + 0x00 + payload<\/code> <\/p>\n\n\n\n<p>v\u00e9rifie les in\u00e9galit\u00e9s <\/p>\n\n\n\n<p><code>2^(8*k - 15) &lt;= m &lt; 2^(8*k - 15) + 2^(8k - 16)<\/code>.<\/p>\n\n\n\n<p>Si l&rsquo;attaquant ne conna\u00eet pas <code>m<\/code> (il souhaite le retrouver !),<\/p>\n\n\n\n<p>il conna\u00eet <code>c = m^e mod n<\/code>.<\/p>\n\n\n\n<p>Il peut \u00e9galement calculer <code>c1 = (c * s^e) mod n = (m*s)^e mod n<\/code> <\/p>\n\n\n\n<p>pour la valeur <code>s<\/code> de son choix.<\/p>\n\n\n\n<p>Le fait que le message (m*s) soit valide entra\u00eene les in\u00e9galit\u00e9s suivantes :<\/p>\n\n\n\n<p><code>2^(8*k - 15) &lt;= m*s &lt; 2^(8*k - 15) + 2^(8k - 16)<\/code>.<\/p>\n\n\n\n<p>En choisissant convenablement <code>s<\/code>, l&rsquo;attaquant peut, au fil des requ\u00eates, obtenir un encadrement de plus en plus pr\u00e9cis de <code>m<\/code> et <em>in fine<\/em> d\u00e9terminer sa valeur.<\/p>\n\n\n\n<p>Ainsi, cette attaque peut \u00eatre men\u00e9e de la mani\u00e8re suivante lorsque le <code>pre_master_secret<\/code> est enti\u00e8rement g\u00e9n\u00e9r\u00e9 par le client :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;attaquant est en position de MitM et intercepte le trafic \u00e9chang\u00e9 entre le client et le serveur ;<\/li>\n\n\n\n<li>Il lance l&rsquo;attaque contre le serveur. ici <code>c<\/code> est le contenu du <code>ClientKeyExchange<\/code>. Chaque tentative n\u00e9cessite d&rsquo;initier un handshake au cours duquel est envoy\u00e9 un <code>ClientKeyExchange<\/code> modifi\u00e9 contenant <code>c1<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>L&rsquo;attaque permet de retrouver le <code>pre_master_secret<\/code> apr\u00e8s de l&rsquo;ordre d&rsquo;un million de requ\u00eates.<\/p>\n\n\n\n<p>Cette attaque a \u00e9t\u00e9 corrig\u00e9e par plusieurs contremesures :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Suppression de l&rsquo;oracle de padding dans TLSv1.0 ;<\/li>\n\n\n\n<li>Utilisation \u00e0 partir de TLSv1.1 de la version 2 de PKCS#1 qui rend cette attaque impossible.<\/li>\n<\/ul>\n\n\n\n<p>L&rsquo;utilisation d&rsquo;un \u00e9change Diffie-Hellman rend \u00e9galement inop\u00e9rante cette attaque.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Oracle de padding dans CBC<\/strong><\/h4>\n\n\n\n<p>Comme la pr\u00e9c\u00e9dente, cette attaque exploite le fait qu&rsquo;un oracle de padding va divulguer de l&rsquo;information sur un message chiffr\u00e9. Cependant, ce n&rsquo;est pas le <code>pre_master_secret<\/code> qui est vis\u00e9 ici, mais le contenu applicatif.<\/p>\n\n\n\n<p>L&rsquo;attaque par oracle de padding dans le mode CBC a \u00e9t\u00e9 d\u00e9couverte par Serge Vaudenay au d\u00e9but des ann\u00e9es 2000 (https:\/\/www.iacr.org\/archive\/eurocrypt2002\/23320530\/cbc02_e02d.pdf) et appliqu\u00e9e \u00e0 SSL peu de temps apr\u00e8s (https:\/\/www.iacr.org\/cryptodb\/archive\/2003\/CRYPTO\/1069\/1069.pdf).<\/p>\n\n\n\n<p>Dans ce dernier article, la mise en oeuvre de l&rsquo;attaque permettait de retrouver le mot de passe d&rsquo;un compte IMAP en une dur\u00e9e de l&rsquo;ordre de l&rsquo;heure.<\/p>\n\n\n\n<p>Pour rappel, dans le mode CBC le chiffrement d&rsquo;un bloc de clair fait intervenir le bloc de chiffr\u00e9 pr\u00e9c\u00e9dent, selon la relation :<\/p>\n\n\n\n<p><code>Yi = E(Xi ^ Yi-1)<\/code>.<\/p>\n\n\n\n<p>Comme ce mode est utilis\u00e9 par des algorithmes de chiffrement par bloc, la taille des donn\u00e9es \u00e0 chiffrer doit \u00eatre un multiple de la taille du bloc, ce qui impose d&rsquo;utiliser un padding.<\/p>\n\n\n\n<p>Une fa\u00e7on courante de padder est d&rsquo;ajouter \u00e0 padding o\u00f9 chaque octet de padding a une valeur \u00e9gale \u00e0 la longueur de ce padding (ainsi le bloc de padding est <code>0x01<\/code>, ou <code>0x0202<\/code>, ou bien <code>0x030303<\/code>, etc).<\/p>\n\n\n\n<p>Un oracle de padding est pr\u00e9sent dans la fonction r\u00e9alisant le d\u00e9chiffrement si cette derni\u00e8re se comporte diff\u00e9remment selon que ce padding soit valide ou non.<\/p>\n\n\n\n<p>Supposons donc que deux blocs, <code>(C1, C2)<\/code>, chiffr\u00e9s de <code>(P1, P2)<\/code>, aient \u00e9t\u00e9 intercept\u00e9s.<\/p>\n\n\n\n<p>Le but final de l&rsquo;attaquant est de retrouver <code>P2<\/code>, qui v\u00e9rifie la relation <code>P2 = D(C2) ^ C1<\/code>.<\/p>\n\n\n\n<p>Pour cela, il va soumettre \u00e0 la fonction de d\u00e9chiffrement ayant un oracle de padding des messages <code>(\u00c71, C2)<\/code>, o\u00f9 <code>\u00c71 = C1 ^ delta<\/code>.<\/p>\n\n\n\n<p>L&rsquo;attaquant commence par choisir <code>delta<\/code> au hasard.<\/p>\n\n\n\n<p>Il soumet \u00e0 l&rsquo;oracle des couples <code>(\u00c71, C2)<\/code>, en modifiant le dernier octet de <code>delta<\/code>.<\/p>\n\n\n\n<p>Au bout d&rsquo;un certain nombre d&rsquo;it\u00e9rations (256 au plus), un des <code>(\u00c71, C2)<\/code> finit par \u00eatre accept\u00e9, au sens o\u00f9 <code>D(C2) ^ \u00c71<\/code> est un bloc correctement padd\u00e9.<\/p>\n\n\n\n<p>Lorsque cet \u00e9v\u00e9nement se produit, la situation la plus probable est que le dernier octet de <code>D(C2) ^ \u00c71<\/code> soit <code>0x01<\/code>, ce qui d\u00e9termine la valeur de <code>D(C2)<\/code>.<\/p>\n\n\n\n<p>L&rsquo;attaquant peut alors modifier le dernier octet de delta de fa\u00e7on \u00e0 s&rsquo;assurer que le dernier octet de <code>D(C2) ^ \u00c71<\/code> vaille <code>0x02<\/code>. Il va alors soumettre des couples <code>(\u00c71, C2)<\/code> en jouant sur l&rsquo;avant-dernier octet de <code>delta<\/code>, jusqu&rsquo;\u00e0 ce que <code>(\u00c71, C2)<\/code> soit accept\u00e9 : le padding de <code>D(C2) ^ \u00c71<\/code> est de nouveau correct et l&rsquo;hypoth\u00e8se la plus vraisemblable est que ce bloc se termine par <code>0x0202<\/code>, ce qui d\u00e9termine l&rsquo;avant-dernier octet de <code>D(C2)<\/code>.<\/p>\n\n\n\n<p>\u00c0 ce stade, les deux derniers octets de <code>D(C2)<\/code> sont connus et en it\u00e9rant le proc\u00e9d\u00e9 l&rsquo;attaquant finit par d\u00e9terminer <code>D(C2)<\/code>, et donc <code>P2 = D(C2) ^ C1<\/code>.<\/p>\n\n\n\n<p>Un oracle de padding \u00e9tait pr\u00e9sent dans les versions ant\u00e9rieures \u00e0 TLSv1.1, qui reagissaient diff\u00e9remment selon que le padding d&rsquo;un message soit incorrect (l&rsquo;alerte <code>decryption_failed<\/code> \u00e9tait retourn\u00e9e) ou que le MAC soit incorrect (l&rsquo;alerte <code>bad_record_mac<\/code> \u00e9tait retourn\u00e9e). Comme la v\u00e9rification du MAC est r\u00e9alis\u00e9 apr\u00e8s la v\u00e9rification du padding, un MAC incorrect indique en creux que le padding est correct.<\/p>\n\n\n\n<p>Cet oracle a \u00e9t\u00e9 corrig\u00e9 dans TLSv1.1, qui retourne <code>bad_record_mac<\/code> dans tous les cas.<\/p>\n\n\n\n<p>Cela ne r\u00e8gle pas compl\u00e8tement la question, comme l&rsquo;attaque Lucky 13 l&rsquo;a montr\u00e9 : si le padding est correct, le padding est v\u00e9rifi\u00e9 et le traitement du message sera un peu plus long, ce qui constitue une fuite d&rsquo;information.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Les faiblesses statistiques de RC4<\/strong><\/h5>\n\n\n\n<p>Contrairement \u00e0 la plupart des algorithmes de chiffrement sym\u00e9triques utilis\u00e9s par SSL\/TLS, RC4 est un algorithme de chiffrement par flot : il g\u00e9n\u00e8re une suite d&rsquo;octets avec lesquels sont xor\u00e9s les octets de message clairs.<\/p>\n\n\n\n<p>Par cons\u00e9quent, pour que l&rsquo;algorithme soit cryptographiquement \u00ab\u00a0solide\u00a0\u00bb, il faut que la suite d&rsquo;octets g\u00e9n\u00e9r\u00e9s ait de \u00ab\u00a0bonnes\u00a0\u00bb propri\u00e9t\u00e9s statistiques et soit indistinguable d&rsquo;une suite g\u00e9n\u00e9r\u00e9e au hasard.<\/p>\n\n\n\n<p>RC4 a \u00e9t\u00e9 cr\u00e9\u00e9 par Ronald Rivest (le &lsquo;R&rsquo; de &lsquo;RSA&rsquo; !) en 1987. D\u00e8s 1995, des faiblesses ont \u00e9t\u00e9 detect\u00e9es dans RC4.<\/p>\n\n\n\n<p>Malgr\u00e9 cela, l&rsquo;algorithme, tr\u00e8s simple d&rsquo;impl\u00e9mentation et tr\u00e8s rapide, a \u00e9t\u00e9 massivement utilis\u00e9 (dans la premi\u00e8re moiti\u00e9 des ann\u00e9es 2010, jusqu&rsquo;\u00e0 50 % du trafic SSL\/TLS \u00e9tait chiffr\u00e9 avec RC4 !).<\/p>\n\n\n\n<p>Une perc\u00e9e majeure a \u00e9t\u00e9 publi\u00e9e en 2013 (https:\/\/web.archive.org\/web\/20130922170155\/http:\/\/www.isg.rhul.ac.uk\/tls\/RC4biases.pdf) par des chercheurs anglais qui ont montr\u00e9 que l&rsquo;exploitation de biais statistiques permettait de retrouver un octet de clair parmis les 256 premiers octets envoy\u00e9s lors d&rsquo;une session TLS, pour peu que le m\u00eame message soit envoy\u00e9 dans 2^32 sessions diff\u00e9rentes.<\/p>\n\n\n\n<p>C&rsquo;est typiquement le cas d&rsquo;un identifiant de connexion (cookie ou assimil\u00e9) qui sera envoy\u00e9 tout au long de sa dur\u00e9e de vie au fil des sessions TLS (si l&rsquo;on reste connect\u00e9 plusieurs jours, voire plusieurs mois sur <code>marmiton.org<\/code>, le m\u00eame identifiant de connexion sera envoy\u00e9 d\u00e8s le d\u00e9but de chaque session TLS).<\/p>\n\n\n\n<p>Le nombre de sessions n\u00e9cessaire (plus de quatre milliards !) reste cependant tr\u00e8s \u00e9lev\u00e9.<\/p>\n\n\n\n<p>Un nouveau r\u00e9sultat spectaculaire fut publi\u00e9 en 2015 (https:\/\/www.rc4nomore.com\/) par des chercheurs hollandais.<\/p>\n\n\n\n<p>Leur attaque permet, dans les m\u00eames circonstances, de retrouver un cookie si il est envoy\u00e9 2^27 fois. Cette attaque est une <em>ciphertext-only attack<\/em> : il suffit de collecter suffisamment de trafic chiffr\u00e9 pour pouvoir la r\u00e9aliser, ce qui la rend r\u00e9aliste.<\/p>\n\n\n\n<p>Finalement, l&rsquo;usage de RC4 dans TLS a \u00e9t\u00e9 interdit par la RFC 7465, publi\u00e9e en 2015.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Collision de blocs chiffr\u00e9s : Sweet 32<\/strong><\/h4>\n\n\n\n<p>Une faiblesse g\u00e9n\u00e9rique des algorithmes de chiffrement par bloc est qu&rsquo;au bout d&rsquo;un certain nombre de messages chiffr\u00e9s, des collisions se produisent, collisions qui peuvent faire fuiter de l&rsquo;information sur les messages clairs.<\/p>\n\n\n\n<p>Par exemple, dans le mode CBC chaque bloc de chiffr\u00e9 est calcul\u00e9 avec la formule <code>Yi = Ek(Xi ^ Yi-1)<\/code>. Si deux blocs, <code>Yi<\/code> et <code>Yj<\/code> sont en collision,<\/p>\n\n\n\n<p>alors <code>Yi = Yj<\/code>, d&rsquo;o\u00f9<\/p>\n\n\n\n<p><code>Ek(Xi ^ Yi-1) = Ek(Xj ^ Yj-1)<\/code>, donc en d\u00e9chiffrant<\/p>\n\n\n\n<p><code>Xi ^ Yi-1 = Xj ^ Yj-1<\/code>, ce qui entra\u00eene<\/p>\n\n\n\n<p><code>Xi ^ Xj = Yi-1 ^ Yj-1<\/code> : le xor de deux messages clair est \u00e9gal au xor (connu !) de deux messages chiffr\u00e9s, ce qui peut avoir des cons\u00e9quences facheuses si la nature des \u00e9changes fait qu&rsquo;une partie de <code>Xi<\/code> peut \u00eatre connue.<\/p>\n\n\n\n<p>Du fait du paradoxe des anniversaires, une collision entre deux messages chiffr\u00e9s a une probabilit\u00e9 significative de se produire d\u00e8s que le nombre de messages chiffr\u00e9s est \u00e9gal \u00e0 la racine carr\u00e9e du nombre de bloc possibles.<\/p>\n\n\n\n<p>Plus clairement, dans le cas d&rsquo;un algorithme de chiffrement utilisant des blocs 64 bits (comme DES, 3DES ou Blowfish), alors une collision a une chance significative de se produire d\u00e8s que que 2^32 bloc ont \u00e9t\u00e9 \u00e9chang\u00e9s.<\/p>\n\n\n\n<p>Cette vuln\u00e9rabilit\u00e9 g\u00e9n\u00e9rique \u00e9tait connue depuis longtemps, mais en 2016 des chercheurs s&rsquo;y sont int\u00e9ress\u00e9 d&rsquo;un peu plus pr\u00e8s, en tirant profit de certaines particularit\u00e9s du trafic vis\u00e9, comme :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>l&rsquo;envoi r\u00e9p\u00e9t\u00e9 d&rsquo;un secret fixe (ce qui est typiquement le cas d&rsquo;un cookie),<\/li>\n\n\n\n<li>Le fait qu&rsquo;une partie du plaintext est connue (comme <code>GET HTTP\/1.1\\r\\n<\/code>, par exemple).<\/li>\n<\/ul>\n\n\n\n<p>L&rsquo;\u00e9quipe en question a \u00e9galement utilis\u00e9 une technique du type \u00ab\u00a0Man-In-The-Browser\u00a0\u00bb, qui s&rsquo;apparente \u00e0 une attaque CSRF : les attaquants, qui s&rsquo;int\u00e9resse \u00e0 la connexion de la victime sur <code>lapin.com<\/code>, l&rsquo;am\u00e8nent \u00e0 visiter <code>attaquant.org<\/code>, qui va t\u00e9l\u00e9charger un script du style :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script&gt;\n    je fais plein de requ\u00eates vers lapin.com\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>L&rsquo;attaque est d\u00e9taill\u00e9e sur https:\/\/sweet32.info\/SWEET32_CCS16.pdf.<\/p>\n\n\n\n<p>Ici la Same-Origin-Policy interdit au script de prendre connaissance de la r\u00e9ponse \u00e0 ses requ\u00eates, mais qu&rsquo;importe, le seul but du script est de g\u00e9n\u00e9rer une grande quantit\u00e9 de trafic vers <code>lapin.com<\/code> embarquant le cookie vis\u00e9.<\/p>\n\n\n\n<p>L&rsquo;attaque permet d&rsquo;extraire un cookie de 16 octets apr\u00e8s avoir intercept\u00e9 705 Go de trafic, g\u00e9n\u00e9r\u00e9 en 18,6 heures.<\/p>\n\n\n\n<p>Ind\u00e9pendamment des m\u00e9canismes propres au navigateur (\u00ab\u00a0l&rsquo;amplification de trafic\u00a0\u00bb bas\u00e9e sur le script malveillant ne marche plus dans le cas d&rsquo;un token JWT ou d&rsquo;un cookie dont l&rsquo;attribut <code>SameSite<\/code> est correctement positionn\u00e9), une contremesure simple est de n&rsquo;utiliser que des algorithmes utilisant des blocs de 128 bits.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Les suites EXPORT<\/strong><\/h4>\n\n\n\n<p>Entre le moment o\u00f9 elle est sortie des entit\u00e9s r\u00e9galiennes et son adoption massive pour des usages quotidiens, la cryptographie a connu dans les ann\u00e9es 1990 une phase de transition o\u00f9 son utilisation \u00e9tait r\u00e9gul\u00e9e par des lois imposant des restrictions en terme de r\u00e9sistance \u00e0 la cryptanalyse.<\/p>\n\n\n\n<p>Aux \u00c9tats-Unis, jusqu&rsquo;en 1999 l&rsquo;export de logiciel ou mat\u00e9riel embarquant des m\u00e9canismes cryptographiques ayant des cl\u00e9s sym\u00e9triques de plus de 40 bits ou des cl\u00e9s asym\u00e9triques de plus de 512 bits \u00e9tait par cons\u00e9quent interdit. Par cons\u00e9quent, des suites cryptographiques \u00ab\u00a0exportables\u00a0\u00bb furent incorpor\u00e9es dans SSLv3.<\/p>\n\n\n\n<p>Dans ces suites export, l&rsquo;algorithme de chiffrement (RC2, RC4 ou DES) utilisait une cl\u00e9 de chiffrement de 40 bits, la cl\u00e9 priv\u00e9e de RSA ou DSS avait une taille de 512 bits.<\/p>\n\n\n\n<p>Le bridage \u00e0 40 bits se faisait en utilisant un m\u00e9canisme de d\u00e9rivation d\u00e9di\u00e9. L&rsquo;usage de ces suites exportables a \u00e9t\u00e9 interdit \u00e0 partir de TLSv1.1.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>DHE versus DH<\/strong><\/h4>\n\n\n\n<p>Lorsqu&rsquo;une suite utilisant le m\u00e9canisme d&rsquo;\u00e9change DHE est utilis\u00e9e, le serveur envoie au client dans un message <code>ServerKeyExchange<\/code> une demi-cl\u00e9 <code>Ys =g^s mod p<\/code> sign\u00e9e et le client lui envoie un <code>ClientKeyExchange<\/code> contenant une demi-cl\u00e9 <code>Yc = g^c mod p<\/code>. Chaque partie reconstitue <code>g^sc mod p<\/code> qui constitue le <code>pre_master_secret<\/code>.<\/p>\n\n\n\n<p>Si le trafic est intercept\u00e9 et que la cl\u00e9 priv\u00e9e du serveur est compromise, un attaquant purement passif ne peut pas faire grand chose : il devrait savoir r\u00e9soudre le probl\u00e8me du logarithme discret pour retrouver le <code>pre_master_secret<\/code>, les secrets <code>s<\/code> et <code>c<\/code> \u00e9tant <em>\u00e9ph\u00e9m\u00e8res<\/em>.<\/p>\n\n\n\n<p>Comme le nom ne l&rsquo;indique pas, les suites utilisant le m\u00e9canisme DH sont assez diff\u00e9rentes : ici, le serveur utilise un secret <code>s<\/code> qui a une <em>longue<\/em> dur\u00e9e de vie : en cas de compromission du serveur, il est tout aussi susceptible d&rsquo;\u00eatre vol\u00e9 que la cl\u00e9 priv\u00e9e. Ces suites n&rsquo;assure donc pas la PFS.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>DH anonymous<\/strong><\/h4>\n\n\n\n<p>Dans ces suites, la demi-cl\u00e9 du serveur n&rsquo;est pas sign\u00e9e : un attaquant peut parfaitement la remplacer par une demi-cl\u00e9 de son choix. Autant dire que ces suites n&rsquo;offrent aucune s\u00e9curit\u00e9 !<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Les vuln\u00e9rabilit\u00e9s protocolaires<\/strong><\/h3>\n\n\n\n<p>Ces vuln\u00e9rabilit\u00e9s sont dues \u00e0 des incoh\u00e9rences ou a des erreurs de conception inh\u00e9rentes au protocole TLS.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>BEAST<\/strong><\/h4>\n\n\n\n<p>L&rsquo;attaque BEAST (Browser Exploit Against Ssl\/Tls), publi\u00e9e en 2011, exploite le fait que jusque \u00e0 TLSv1.0, le dernier bloc chiffr\u00e9 d&rsquo;un message est utilis\u00e9 comme vecteur d&rsquo;initialisation pour chiffrer le prochain message.<\/p>\n\n\n\n<p>Consid\u00e9rons une connexion TLS, dans laquelle l&rsquo;attaquant aimerait d\u00e9terminer la valeur d&rsquo;un bloc <code>P_i<\/code>.<\/p>\n\n\n\n<p>Le bloc chiffr\u00e9 <code>C_i<\/code> est calcul\u00e9 selon la relation <code>C_i = E(P_i ^ C_i-1)<\/code>.<\/p>\n\n\n\n<p>Le bloc <code>C_i<\/code> fait partie d&rsquo;un message TLS, dont le dernier bloc <code>C_j-1<\/code> est utilis\u00e9 comme vecteur d&rsquo;initialisation du prochain message TLS envoy\u00e9.<\/p>\n\n\n\n<p>Ainsi, on a la relation <code>C_j = E(P_j ^ C_j-1)<\/code>.<\/p>\n\n\n\n<p>Notre attaquant est en mesure d&rsquo;observer le trafic TLS : Il conna\u00eet donc les blocs <code>C_i<\/code>, <code>C_i-1<\/code>, <code>C_j-1<\/code>, <code>C_j<\/code>. De plus, il contr\u00f4le <code>P_j<\/code>.<\/p>\n\n\n\n<p>Dans cette situation, il est capable de d\u00e9terminer si le bloc <code>P_i<\/code> vaut ou non <code>x<\/code> :<\/p>\n\n\n\n<p>Pour cela, il utilise <code>P_j = C_j-1 ^ C_i-1 ^ x<\/code>. Si l&rsquo;on a bien <code>P_i = x<\/code>, alors<\/p>\n\n\n\n<p><code>C_j = E(C_j-1 ^ Pj) = E(C_j-1 ^ C_j-1 ^ C_i-1 ^ x) = E(C_i-1 ^ x) = E(C_i-1 ^ Pi) = C_i<\/code>.<\/p>\n\n\n\n<p>Dans le sc\u00e9nario d\u00e9crit par l&rsquo;article https:\/\/nerdoholic.org\/uploads\/dergln\/beast_part2\/ssl_jun21.pdf, l&rsquo;attaquant tente de retrouver le cookie de session authentifiant la victime sur <code>https:\/\/www.pigeon.fr<\/code>.<\/p>\n\n\n\n<p>Ce sc\u00e9nario peut \u00eatre mis en oeuvre ainsi :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;attaquant am\u00e8ne la victime visiter <code>attaquant.org<\/code>, qui t\u00e9l\u00e9charge un script envoyant des requ\u00eates vers <code>https:\/\/www.pigeon.fr<\/code>. Le cookie de la victime sera incorpor\u00e9 \u00e0 ces requ\u00eates.<\/li>\n\n\n\n<li>L&rsquo;attaquant est en mesure d&rsquo;observer le trafic chiffr\u00e9 g\u00e9n\u00e9r\u00e9 par ce script.<\/li>\n<\/ul>\n\n\n\n<p>Le script va alors forger des requ\u00eates de la forme <code>POST \/PAAAAAAAAAAAAAAAAAAAAAAAAAAADDING HTTP \/1.1\\r\\n<\/code> vers <code>https:\/\/www.pigeon.fr<\/code>. Comme le cookie de la victime est incorpor\u00e9 \u00e0 la requ\u00eate, la requ\u00eate effectivement \u00e9mise est en fait <code>POST \/PAAAAAAAAAAAAAAAAAAAAAAAAAAADDING HTTP \/1.1\\r\\nCookie: adm=patate_douce<\/code>.<\/p>\n\n\n\n<p>Cette requ\u00eate est d\u00e9coup\u00e9e en plusieurs bloc lors avant chiffrement :<\/p>\n\n\n\n<p><code>P_i-3<\/code> = <code>POST \/PAAAAAAAAA<\/code><br><code>P_i-2<\/code> = <code>AAAAAAAAAAAAAAAA<\/code><br><code>P_i-1<\/code> = <code>AADDING HTTP \/1.<\/code><br><code>P_i <\/code>= <code>1\\r\\nCookie: adm=p<\/code>.<\/p>\n\n\n\n<p>Ainsi, un seul octet de <code>P_i<\/code> est inconnu. Pour toutes les 256 valeurs possibles de cet octet, l&rsquo;attaquant<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>construit <code>x<\/code> comme \u00e9tant \u00e9gal au 15 premiers octets de <code>P_i<\/code>, qui sont fixes et connus, suivi de l&rsquo;octet-candidat,<\/li>\n\n\n\n<li>soumet une requ\u00eate commen\u00e7ant par <code>P_j = C_j-1 ^ C_i-1 ^ x<\/code>. <\/li>\n\n\n\n<li>Il est en mesure de forger une telle requ\u00eate, car il peut observer <code>C_j-1<\/code> et <code>C_i-1<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Si <code>x<\/code> est \u00e9gal \u00e0 <code>P_i<\/code>, alors <code>C_j<\/code> = <code>C_i<\/code>.<\/p>\n\n\n\n<p>En jouant sur la longueur du padding, l&rsquo;attaquant peut aboutir \u00e0 <\/p>\n\n\n\n<p><code>P_i<\/code> = <code>\\r\\nCookie: adm=pa<\/code>, <\/p>\n\n\n\n<p>deviner le 2\u00e8me caract\u00e8re du cookie de session, puis provoquer l&rsquo;envoi de <\/p>\n\n\n\n<p><code>P_i<\/code> = <code>\\nCookie: adm=pat<\/code>, <\/p>\n\n\n\n<p>deviner le 3\u00e8me octet du cookie de session et ainsi de suite.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Compression, le revers de la m\u00e9daille &#8211; CRIME<\/strong><\/h4>\n\n\n\n<p>CRIME est l&rsquo;acronyme de Compression Ratio Info-leak Made Easy. Cette attaque d\u00e9couverte en 2012 utilise le taux de compression des messages comme canal auxiliaire, lorsque TLS utilise un m\u00e9canisme de compression.<\/p>\n\n\n\n<p>Vu d&rsquo;avion, un algorithme de compression supprime les redondances pr\u00e9sentes dans un message et r\u00e9duira plus fortement la taille d&rsquo;un message comportant beaucoup de redondances qu&rsquo;un message en comportant peu.<\/p>\n\n\n\n<p>Cette propri\u00e9t\u00e9 peut \u00eatre exploit\u00e9e pour retrouver un cookie, en mettant en oeuvre une attaque \u00ab\u00a0Man-In-The-Browser\u00a0\u00bb :<\/p>\n\n\n\n<p>On vise le cookie <code>auth=sandwichbanane<\/code> que la victime incorpore aux requ\u00eates qu&rsquo;elle envoie \u00e0 <code>https:\/\/www.poulet.fr<\/code>.<\/p>\n\n\n\n<p>L&rsquo;attaquant am\u00e8ne la victime \u00e0 visiter <code>attaquant.org<\/code>, qui va t\u00e9l\u00e9charger un script.<\/p>\n\n\n\n<p>Le script enverra des requ\u00eates HTTP \u00e0 <code>https:\/\/www.poulet.fr<\/code>, avec le cookie vis\u00e9 et un cookie suppl\u00e9mentaire <code>auth=UneValeurInitialementAl\u00e9atoire<\/code>.<\/p>\n\n\n\n<p>L&rsquo;attaquant, \u00e9galement en position de MiTM, est capable de mesurer la taille des paquets TLS envoy\u00e9s \u00e0 <code>https:\/\/www.poulet.fr<\/code>. Lorsque la taille du paquet envoy\u00e9 diminue, cela signifie qu&rsquo;un des caract\u00e8res du cookie a \u00e9t\u00e9 trouv\u00e9.<\/p>\n\n\n\n<p>En effet, le script va envoyer des requ\u00eates de ce type :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/truc HTTP\/1.1\nHost:www.poulet.fr\nBla\nCookie: auth=sandwichbanane;auth=ilkdfjsdlkfjls<\/code><\/pre>\n\n\n\n<p>or cette requ\u00eate sera moins fortement compress\u00e9e que celle-ci :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/truc HTTP\/1.1\nHost:www.poulet.fr\nBla\nCookie: auth=sandwichbanane;auth=sakdfjsdlkfjls<\/code><\/pre>\n\n\n\n<p>qui sera elle-m\u00eame moins compress\u00e9e que celle-l\u00e0 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/truc HTTP\/1.1\nHost:www.poulet.fr\nBla\nCookie: auth=sandwichbanane;auth=sandwisdlkfjls<\/code><\/pre>\n\n\n\n<p>et ainsi de suite.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Compression, le revers de la m\u00e9daille &#8211; BREACH<\/strong><\/h4>\n\n\n\n<p>BREACH pour Browser Reconnaissance and Exfiltration via Adaptative Compression of Hypertext.<\/p>\n\n\n\n<p>Comme CRIME, cette attaque exploite le taux de compression des messages comme canal auxiliaire ; Cependant, ici, c&rsquo;est l&rsquo;utilisation d&rsquo;un m\u00e9canisme de compression par la couche HTTP qui est vis\u00e9e.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Compression, le revers de la m\u00e9daille &#8211; TIME<\/strong><\/h4>\n\n\n\n<p>Comme BREACH, l&rsquo;attaque TIME (Time Info-leak Made Easy) se base sur l&rsquo;utilisation de compression.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Compression, le revers de la m\u00e9daille &#8211; HEIST<\/strong><\/h4>\n\n\n\n<p>HEIST (HTTP Encrypted Information Stolen through TCP-windows) est un raffinement des attaques exploitant le taux de compression comme canal auxiliaire : les modifications de la taille de la fen\u00eatre TCP entre client et serveur est utilis\u00e9e pour inf\u00e9rer la longueur des messages \u00e9chang\u00e9s.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>La dur\u00e9e de traitement d&rsquo;un message comme oracle de padding &#8211; Lucky 13<\/strong><\/h4>\n\n\n\n<p>Ou le retour de l&rsquo;oracle de padding dans CBC. Lorsque le mode Mac-Then-Encrypt est utilis\u00e9, un MAC sur le message clair est calcul\u00e9 et ajout\u00e9 \u00e0 la fin de ce message. Le tout est padd\u00e9, puis chiffr\u00e9.<\/p>\n\n\n\n<p>Jusqu&rsquo;\u00e0 SSLv3, le message d&rsquo;alerte envoy\u00e9 lorsque le padding \u00e9tait incorrect n&rsquo;\u00e9tait pas le m\u00eame que lorsque le MAC \u00e9tait erron\u00e9, constituant ainsi un oracle de padding.<\/p>\n\n\n\n<p>M\u00eame avec cette contremesure, un oracle de padding reste pr\u00e9sent : si le padding est correct, le MAC sera calcul\u00e9 et le r\u00e9cepteur renverra le message d&rsquo;alerte un peu moins vite que si le padding est incorrect.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>SLOTH<\/strong><\/h4>\n\n\n\n<p>SLOTH (acronyme de \u00ab\u00a0Security Losses from Obsolete and Truncated Transcript Hashes\u00a0\u00bb), publi\u00e9e en 2016 (https:\/\/www.mitls.org\/pages\/attacks\/SLOTH), englobe une s\u00e9rie d&rsquo;attaques dans lesquelles l&rsquo;utilisation de fonctions de hachage obsol\u00e8tes (MD5 et SHA-1) dans l&rsquo;algorithme de signature d&rsquo;un certificat entra\u00eene une d\u00e9gradation significative de la s\u00e9curit\u00e9 de la session TLS.<\/p>\n\n\n\n<p>L&rsquo;attaque la plus spectaculaire est probablement celle permettant \u00e0 un attaquant d&rsquo;usurper l&rsquo;identit\u00e9 d&rsquo;un client dans le cas d&rsquo;une authentification mutuelle. Elle exploite le fait qu&rsquo;il est calculatoirement possible de trouver des collisions \u00e0 prefixes choisis dans MD5, c&rsquo;est-\u00e0-dire qu&rsquo;\u00e9tant donn\u00e9s <code>P1<\/code> et <code>P2<\/code> choisis, il est possible de calculer <code>C1<\/code> et <code>C2<\/code> tels que <code>MD5(P1 + C1) = MD5(P2 + C2)<\/code>. Mener une telle attaque demande de r\u00e9aliser 2^39 calculs MD5.<\/p>\n\n\n\n<p>Le sc\u00e9nario de l&rsquo;attaque est le suivant :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;attaquant est en position de MitM entre le client et le serveur. Il poss\u00e8de un certificat sign\u00e9 par une autorit\u00e9 de certification connue du client et souhaite se faire passer pour le client aupr\u00e8s du serveur.<\/li>\n\n\n\n<li>Le client se connecte \u00e0 l&rsquo;attaquant. Ils \u00e9changent successivement un <code>ClientHello<\/code>, un <code>ServerHello<\/code>, un <code>ServerCertificate<\/code> et un <code>ServerKeyExchange<\/code>.<\/li>\n\n\n\n<li>L&rsquo;attaquant lance alors une recherche de collision MD5 \u00e0 pr\u00e9fixes choisis : il utilise comme pr\u00e9fixe <code>P1<\/code> la concat\u00e9nation des messages \u00e9chang\u00e9s jusqu&rsquo;ici avec le client et pour pr\u00e9fixe <code>P2<\/code> le <code>client.random<\/code> qu&rsquo;il va incoroporer au <code>ClientHello<\/code> qu&rsquo;il enverra au serveur. Les \u00e9l\u00e9ments <code>C1<\/code> et <code>C2<\/code> retourn\u00e9s par l&rsquo;algorithme de recherche de collision est utilis\u00e9 d&rsquo;une part comme extensions incorpor\u00e9es dans le <code>ClientHello<\/code> qu&rsquo;il enverra au serveur, comme liste d&rsquo;autorit\u00e9 de certifications \u00e0 inclure dans le message CertificateRequest qu&rsquo;il enverra au client d&rsquo;autre part.<\/li>\n\n\n\n<li>L&rsquo;attaquant initie alors un handshake avec le serveur et poursuit le handshake d\u00e9but\u00e9 avec le client en parall\u00e8le.<\/li>\n\n\n\n<li>Le client envoie \u00e0 l&rsquo;attaquant un <code>ClientVerify<\/code>, calcul\u00e9e avec sa cl\u00e9 priv\u00e9e et portant une signature calcul\u00e9e sur le hach\u00e9 MD5 des messages ant\u00e9rieurs du handshake. Comme ce hach\u00e9 est identique au hach\u00e9 MD5 des messages \u00e9chang\u00e9s entre l&rsquo;attaquant et le serveur, la signature pr\u00e9sente dans ce <code>ClientVerify<\/code> est identique \u00e0 celle que calculerait l&rsquo;attaquant s&rsquo;il poss\u00e9dait lui-m\u00eame la cl\u00e9 priv\u00e9e du client. Le <code>ClientVerify<\/code> envoy\u00e9 par le client peut donc \u00eatre transmis au serveur par l&rsquo;attaquant.<\/li>\n\n\n\n<li>\u00c0 ce stade, l&rsquo;attaquant cesse les \u00e9changes avec le client et termine le handshake avec le serveur.<\/li>\n\n\n\n<li>Une fois le handshake avec le serveur termin\u00e9, l&rsquo;attaquant est authentifi\u00e9 avec l&rsquo;identit\u00e9 du client aupr\u00e8s du serveur.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Oracle caus\u00e9 par le support de SSLv2 : DROWN<\/strong><\/h4>\n\n\n\n<p>DROWN est l&rsquo;acronyme de \u00ab\u00a0Decrypting Rsa using Obsolete and Weakened eNcryption\u00a0\u00bb.<\/p>\n\n\n\n<p>Cette attaque tire parti du fait qu&rsquo;un nombre significatif de serveurs TLS, au moment de sa publication en 2016, continuait de supporter SSLv2.<\/p>\n\n\n\n<p>L&rsquo;attaque permet de retrouver le <code>pre_master_secret<\/code> envoy\u00e9 par le client lors d&rsquo;un handshake, en utilisant la pile SSLv2 du serveur comme oracle de padding.<\/p>\n\n\n\n<p>Dans le protocole SSLv2, le client envoie un message <code>ClientMasterKey<\/code>, contenant un <code>master_secret<\/code> chiffr\u00e9 avec la cl\u00e9 publique du serveur : c&rsquo;est l&rsquo;\u00e9quivalent du <code>ClientKeyExchange<\/code> des versions post\u00e9rieures.<\/p>\n\n\n\n<p>Le <code>master_secret<\/code> fait 16 octets. Cependant, lorsqu&rsquo;une suite cryptographique EXPORT est utilis\u00e9e, 11 octets sont envoy\u00e9s en clair et seul 5 octets sont chiffr\u00e9s dans le <code>ClientMasterKey<\/code>.<\/p>\n\n\n\n<p>Lorsqu&rsquo;il re\u00e7oit le <code>ClientMasterKey<\/code>, le serveur en extrait le <code>master_secret<\/code>, d\u00e9rive les cl\u00e9s de session et envoie un message <code>ServerVerify<\/code>.<\/p>\n\n\n\n<p>Un handshake SSLv2 est initi\u00e9 par le ClientHello du client, auquel le serveur r\u00e9pond par un ServerHello. Ce ServerHello contient un challenge.<\/p>\n\n\n\n<p>Ce challenge est r\u00e9-envoy\u00e9 chiffr\u00e9 avec la cl\u00e9 de session du serveur dans le <code>ServerVerify<\/code>.<\/p>\n\n\n\n<p>Par ailleurs, lorsqu&rsquo;il re\u00e7oit un <code>master_secret<\/code> qui n&rsquo;est pas padd\u00e9 correctement, le serveur g\u00e9n\u00e8re un <code>master_secret<\/code> al\u00e9atoire.<\/p>\n\n\n\n<p>Ces diff\u00e9rents \u00e9l\u00e9ments permettent d&rsquo;utiliser le handshake SSLv2 comme un oracle de padding :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;attaquant initie un handshake SSLv2 avec le serveur, en demandant l&rsquo;utilisation d&rsquo;une suite EXPORT.<\/li>\n\n\n\n<li>Le serveur envoie un challenge dans le <code>ServerHello<\/code>.<\/li>\n\n\n\n<li>l&rsquo;attaquant envoie un <code>ClientMasterKey<\/code> (dont il ne conna\u00eet pas le contenu) au serveur.<\/li>\n\n\n\n<li>si le <code>master_secret<\/code> est padd\u00e9 correctement, le serveur l&rsquo;utilise pour chiffrer son challenge. S&rsquo;il n&rsquo;est pas padd\u00e9 correctement, il chiffre le challenge avec un <code>master_secret<\/code> al\u00e9atoire. Dans tous les cas, le challenge chiffr\u00e9 est envoy\u00e9 dans le <code>ServerVerify<\/code>.<\/li>\n\n\n\n<li>l&rsquo;attaquant d\u00e9chiffre le contenu du <code>ServerVerify<\/code> avec les 2^40 valeurs possibles pour la partie secr\u00e8te du <code>master_secret<\/code> (rappelons que si une suite EXPORT est utilis\u00e9e, 88 bits du <code>master_secret<\/code> sont publics). Si le <code>master_secret<\/code> a \u00e9t\u00e9 padd\u00e9 correctement, alors pour une de ces 2^40 valeurs, la valeur d\u00e9chiffr\u00e9e est \u00e9gale au challenge envoy\u00e9. Ce n&rsquo;est pas le cas en cas de padding incorrect.<\/li>\n<\/ul>\n\n\n\n<p>Finalement, l&rsquo;attaque suit la logique suivante :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;attaquant collecte des handshakes TLS o\u00f9 RSA est utilis\u00e9 pour l&rsquo;\u00e9change de cl\u00e9,<\/li>\n\n\n\n<li>L&rsquo;attaquant met en oeuvre une heuristique qui tente de convertir les <code>pre_master_secret<\/code> de 48 octets, chiffr\u00e9s dans le <code>ClientKeyExchange<\/code>, en <code>ClientMasterKey<\/code> contenant 5 octets chiffr\u00e9s.<\/li>\n\n\n\n<li>Chaque <code>ClientMasterKey<\/code> ainsi construit est utilis\u00e9 dans une invocation de l&rsquo;oracle de padding, c&rsquo;est-\u00e0-dire dans un handshake SSLv2 utilisant une suite EXPORT.<\/li>\n<\/ul>\n\n\n\n<p>Finalement, l&rsquo;attaque permet de r\u00e9cup\u00e9rer un <code>pre_master_secret<\/code> chiffr\u00e9 avec une cl\u00e9 RSA de 2048 bits avec le co\u00fbt suivant :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>capture de 1000 handshakes TLS,<\/li>\n\n\n\n<li>40000 handshake SSLv2,<\/li>\n\n\n\n<li>Co\u00fbt calculatoire de l&rsquo;ordre de 2^50 op\u00e9rations.<\/li>\n<\/ul>\n\n\n\n<p>L&rsquo;\u00e9quipe de chercheurs (dont les r\u00e9sultats sont d\u00e9crits en d\u00e9tail dans https:\/\/drownattack.com\/drown-attack-paper.pdf) a pu mener l&rsquo;attaque en moins de 8 heures pour 440 $ sur Amazon EC2.<\/p>\n\n\n\n<p>Ces chiffres sont g\u00e9n\u00e9riques : dans certaines versions d&rsquo;OpenSSL, des erreurs d&rsquo;impl\u00e9mentation de SSLv2 facilitaient l&rsquo;attaque.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Oracle caus\u00e9 par le support de SSLv3 : Poodle<\/strong><\/h4>\n\n\n\n<p>Publi\u00e9e en 2014, POODLE (Padding Oracle on Downgraded Legacy Encryption) est, \u00e0 l&rsquo;instar de DROWN, une attaque utilisant une version obsol\u00e8te de SSL\/TLS commme oracle de padding.<\/p>\n\n\n\n<p>L&rsquo;attaque POODLE utilise le fait que clients et serveurs acceptent de mener une downgrade dance : si le handshake avec TLSv1.2 est un echec, alors on se replie sur TLSv1.1 et ainsi de suite.<\/p>\n\n\n\n<p>Un attquant en position de MitM peut amener client et serveur \u00e0 utiliser SSLv3 et tirer parti de la pr\u00e9sence d&rsquo;un oracle de padding CBC dans ce protocole.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Oracle sur la longueur du <code>pre_master_secret<\/code> : Raccoon<\/strong><\/h4>\n\n\n\n<p>Cette attaque datant de 2020 exploite un canal auxiliaire original : les octets nuls au d\u00e9but du <code>pre_master_secret<\/code> sont ignor\u00e9s lorsque ce dernier est utilis\u00e9 pour calculer le <code>master_secret<\/code>.<\/p>\n\n\n\n<p>Cela signifie que quelque part dans l&rsquo;impl\u00e9mentation du calcul du <code>master_secret<\/code>, un pointeur <code>ptr<\/code> pointant sur le d\u00e9but du <code>pre_master_secret_<\/code> est incr\u00e9ment\u00e9 <code>k<\/code> fois, <code>k<\/code> \u00e9tant le nombre d&rsquo;octets nuls au d\u00e9but du <code>pre_master_secret<\/code> : La dur\u00e9e du handshake varie en fonction du nombre d&rsquo;octets nuls au d\u00e9but du <code>pre_master_secret<\/code>.<\/p>\n\n\n\n<p>Un attaquant dispose ainsi d&rsquo;un oracle indiquant si le premier octet du <code>pre_master_secret<\/code> est nul, oracle qu&rsquo;il peut interroger en initiant un handshake avec un <code>g^x mod p<\/code> de son choix.<\/p>\n\n\n\n<p>Dans les grandes lignes, le sc\u00e9nario de l&rsquo;attaque est le suivant :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;attaquant intercepte du trafic TLS entre un client et un serveur. Ce trafic d\u00e9bute par un handshake au cours duquel le serveur envoie un <code>ServerKeyExchange<\/code> contenant un <code>g^b mod p<\/code> et le client envoie un <code>g^b mod p<\/code> contenu dans le <code>ClientKeyExchange<\/code>.<\/li>\n\n\n\n<li>L&rsquo;attaquant souhaite retrouver le <code>pre_master_secret<\/code> qui vaut <code>g^ab mod p<\/code>.<\/li>\n\n\n\n<li>Il initie des handshakes durant lesquels il utilise <code>g^ri * g^a mod p<\/code> comme demi-cl\u00e9 embarqu\u00e9e dans le <code>ClientKeyExchange<\/code> et ceux pour diff\u00e9rentes valeurs de <code>ri<\/code><\/li>\n\n\n\n<li>Ces valeurs aboutissent \u00e0 des <code>pre_master_secret<\/code> valant <code>g^(ri*b)* g^a*b) mod p<\/code>, pour lesquels on conna\u00eet, gr\u00e2ce \u00e0 l&rsquo;oracle, la valeur de l&rsquo;octet de poids fort.<\/li>\n\n\n\n<li>L&rsquo;attaquant peut ainsi construire un syst\u00e8me d&rsquo;\u00e9quations lui permettant de retrouver <code>g^ab mod p<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>L&rsquo;attaque n&rsquo;est possible que si le serveur r\u00e9utilise le m\u00eame logarithme <code>b<\/code> pour diff\u00e9rentes connexions. C&rsquo;est le cas si une suite Diffie-Hellman statique est employ\u00e9e, mais il a pu \u00eatre observ\u00e9 que certains serveurs r\u00e9utilisaient le m\u00eame <code>b<\/code> pour plusieurs connexions, m\u00eame en cas d&#8217;emploi de Diffie-Hellman eph\u00e9m\u00e8re.<\/p>\n\n\n\n<p>L&rsquo;attaque est d\u00e9crite avec plus de d\u00e9tail sur le site qui lui est consacr\u00e9 : <\/p>\n\n\n\n<p>https:\/\/raccoon-attack.com\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading alignwide\"><strong>Les vuln\u00e9rabilit\u00e9s d&rsquo;environnement<\/strong><\/h3>\n\n\n\n<p>Ces vuln\u00e9rabilit\u00e9s ne sont pas des erreurs pr\u00e9sentes dans TLS ou une impl\u00e9mentation de TLS \u00e0 proprement parler : elles ont pour origine la mani\u00e8re dont est utilis\u00e9e TLS dans les diff\u00e9rentes logiciels faisant intervenir TLS &#8211; les navigateurs web, typiquement.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Les m\u00e9canismes de fallback<\/strong><\/h4>\n\n\n\n<p>En cas d&rsquo;echec du handshake et dans un souci d&rsquo;interop\u00e9rabilit\u00e9, de nombreux clients TLS tentaient un handshake avec une version de TLS inf\u00e9rieure \u00e0 celle initialement utilis\u00e9e et pouvaient se retrouver \u00e0 utiliser TLSv1.0 ou SSLv3.0.<\/p>\n\n\n\n<p>Ce comportement pouvait \u00eatre utilis\u00e9 par un attaquant, qui, en injectant des <code>TCP FIN<\/code> ou <code>RST<\/code> pouvaient provoquer un repli vers version plus vuln\u00e9rable.<\/p>\n\n\n\n<p>La RFC 7507 d\u00e9crit un m\u00e9canisme permettant de d\u00e9tecter des replis ill\u00e9gitimes.<\/p>\n\n\n\n<p>Le principe est le suivant :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lorsqu&rsquo;il r\u00e9alise un fallback (c&rsquo;est-\u00e0-dire lorsqu&rsquo;il initie un handshake pour une version qui n&rsquo;est pas la plus haute version de TLS qu&rsquo;il supporte), le client inclut dans son <code>ClientHello<\/code> la pseudo-suite cryptographique <code>TLS_FALLBACK_SCSV<\/code>.<\/li>\n\n\n\n<li>Dans ces circonstances, le fallback n&rsquo;est l\u00e9gitime que s&rsquo;il est \u00e0 l&rsquo;initiative du serveur, auquel cas la version de TLS propos\u00e9e dans le <code>ClientHello<\/code> est \u00e9gale \u00e0 la version maximale support\u00e9e par le serveur. Si ce n&rsquo;est pas le cas, le fallback n&rsquo;est pas l\u00e9gitime et le serveur interrompt le handshake en \u00e9mettant une alarme <code>inappropriate_fallback<\/code>.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>SSL stripping et HSTS<\/strong><\/h4>\n\n\n\n<p>Le SSL stripping n&rsquo;est pas \u00e0 proprement parler une vuln\u00e9rabilit\u00e9 dans TLS, mais plut\u00f4t une faiblesse dans la logique suivie par un client pour ouvrir une session avec un serveur supportant TLS.<\/p>\n\n\n\n<p>\u00c0 la fin des ann\u00e9es 2000, il \u00e9tait courant qu&rsquo;un site web soit simultan\u00e9ment accessible en clair (<code>http:\/\/www.lapin.com<\/code>, port 80) en en chiffr\u00e9 (<code>https:\/\/www.lapin.com<\/code>, port 443).<\/p>\n\n\n\n<p>Lorsqu&rsquo;un client contactait le serveur sur le port 80, ce dernier lui retournait un redirect 302 le redirigeant vers le serveur https.<\/p>\n\n\n\n<p>Un attaquant en position de MitM peut alors modifier \u00e0 la vol\u00e9e cette r\u00e9ponse HTTP pour rediriger la victime vers une copie du site l\u00e9gitime. Cette victime interagira alors en clair avec le faux site, divulguant ses identifiants de session au passage.<\/p>\n\n\n\n<p>Si le site web en question est uniquement accessible via HTTPS, l&rsquo;attaque reste possible, au prix d&rsquo;un peu de social engineering : l&rsquo;attaquant am\u00e8ne la victime \u00e0 contacter <code>http:\/\/www.lapin.com<\/code>, qu&rsquo;il ma\u00eetrise et intercepte la communication du client.<\/p>\n\n\n\n<p>L&rsquo;en-t\u00eate HSTS (Strict-Transport-Security) emp\u00eache cette vuln\u00e9rabilit\u00e9, en permettant \u00e0 <code>www.lapin.com<\/code> de sp\u00e9cifier au navigateur du client qu&rsquo;il doit toujours utiliser HTTPS pour se connecter \u00e0 <code>www.lapin.com<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading alignwide\"><strong>Les vuln\u00e9rabilit\u00e9s d&rsquo;impl\u00e9mentation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>PRNG de la version debian d&rsquo;OpenSSL<\/strong><\/h4>\n\n\n\n<p>En 2006, l&rsquo;\u00e9quipe en charge de l&rsquo;integration de OpenSSL dans debian a accidentellement comment\u00e9 quelques lignes de code ayant un r\u00f4le critique dans le PRNG d&rsquo;OpenSSL.<\/p>\n\n\n\n<p>L&rsquo;\u00e9quipe en question utilisait l&rsquo;outil Valgrind pour traquer les fuites m\u00e9moires et l&rsquo;utilisation de zones m\u00e9moire non initialis\u00e9es. L&rsquo;une des remont\u00e9es de l&rsquo;outil portait sur une ligne alimentant le PRNG en al\u00e9a : une fois cette ligne comment\u00e9e, la seule source d&rsquo;al\u00e9a du PRNG \u00e9tait le pid du processus appelant\u2026<\/p>\n\n\n\n<p>Les deux lignes supprim\u00e9es contiennent un appel \u00e0 la fonction <code>MD_Update<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>247:\n                MD_Update(&amp;m,buf,j);\n\n467:\n#ifndef PURIFY\n                MD_Update(&amp;m,buf,j); \/* purify complains *\/\n#endif<\/code><\/pre>\n\n\n\n<p>L&rsquo;erreur fut d\u00e9couverte en 2008 : toutes les cl\u00e9s g\u00e9n\u00e9r\u00e9es avec OpenSSL sur debian \u00e9taient \u00e0 jeter !<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Erreur de validation du certificat : <code>\\0<\/code> dans le certificat<\/strong><\/h4>\n\n\n\n<p>Lors de l&rsquo;\u00e9dition 2009 de Black Hat, le chercheur Moxie Marlinspike a pr\u00e9sent\u00e9 une vuln\u00e9rabilit\u00e9 affectant la v\u00e9rification du certificat serveur de plusieurs impl\u00e9mentations de TLS : la comparaison entre le nom de domaine contact\u00e9 et le commonName du certificat s&rsquo;arr\u00eate d\u00e8s qu&rsquo;un caract\u00e8re <code>\\0<\/code> est rencontr\u00e9.<\/p>\n\n\n\n<p>Un attaquant peut ainsi forger un certificat pour <code>www.paypal.com\\0ssl.secureconnection.cc<\/code> qui sera interpr\u00e9t\u00e9 comme un certificat valide pour <code>www.payal.com<\/code>.<\/p>\n\n\n\n<p>Source : https:\/\/www.theregister.com\/2009\/10\/05\/fraudulent_paypay_certificate_published\/<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Erreur de validation du certificat : <code>goto fail<\/code><\/strong><\/h4>\n\n\n\n<p>Le nom de cette vuln\u00e9rabilit\u00e9 (ayant fait l&rsquo;objet de la CVE-2014-1266) le cot\u00e9 client de la pile TLS utilis\u00e9e dans iOS et macOS provient d&rsquo;une instruction surnum\u00e9raire ayant pour effet d&rsquo;omettre toute une s\u00e9rie d&rsquo;\u00e9tapes de la v\u00e9rification d&rsquo;un certificat.<\/p>\n\n\n\n<p>\u00c0 chaque \u00e9tape, en cas d&rsquo;echec le flux d&rsquo;ex\u00e9cution est d\u00e9rout\u00e9 vers le label <code>fail<\/code>, et le code d&rsquo;erreur <code>err<\/code> est retourn\u00e9.<\/p>\n\n\n\n<p>On voit que le deuxi\u00e8me <code>goto fail<\/code> est suivi d&rsquo;un autre <code>goto fail<\/code>, qui lui est toujours ex\u00e9cut\u00e9.<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>static OSStatus\nSSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,\n                                 uint8_t *signature, UInt16 signatureLen)\n{\n    OSStatus        err;\n    ...\n\n    if ((err = SSLHashSHA1.update(&amp;hashCtx, &amp;serverRandom)) != 0)\n        goto fail;\n    if ((err = SSLHashSHA1.update(&amp;hashCtx, &amp;signedParams)) != 0)\n        goto fail;\n        goto fail;\n    if ((err = SSLHashSHA1.final(&amp;hashCtx, &amp;hashOut)) != 0)\n        goto fail;\n    ...\n\nfail:\n    SSLFreeBuffer(&amp;signedHashes);\n    SSLFreeBuffer(&amp;hashCtx);\n    return err;\n}<\/code><\/pre>\n\n\n\n<p>Ainsi, la fonction <code>SSLVerifySignedServerKeyExchange<\/code> retourne un code d&rsquo;erreur signifiant \u00ab\u00a0tout va bien\u00a0\u00bb et les v\u00e9rifications ult\u00e9rieures ne sont pas effectu\u00e9es : Un certficat serveur invalide est accept\u00e9 !<\/p>\n\n\n\n<p>Une vuln\u00e9rabilit\u00e9 similaire (CVE-2014-009) a affect\u00e9 gnuTLS la m\u00eame ann\u00e9e.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Heartbleed<\/strong><\/h4>\n\n\n\n<p>Heartbleed (CVE-2014-0160) est une vuln\u00e9rabilit\u00e9 dans l&rsquo;impl\u00e9mentation OpenSSL du m\u00e9canisme de heartbeat.<\/p>\n\n\n\n<p>C&rsquo;est une vuln\u00e9rabilit\u00e9 permettant de lire dans la m\u00e9moire du serveur TLS : ce n&rsquo;est pas une vuln\u00e9rabilit\u00e9 cryptographique.<\/p>\n\n\n\n<p>Ce m\u00e9canisme de heartbeat est une extension de TLS d\u00e9crite dans la RFC 6520.<\/p>\n\n\n\n<p>Elle permet \u00e0 chaque extremit\u00e9 d&rsquo;une connexion TLS de s&rsquo;assurer que l&rsquo;autre extremit\u00e9 est encore vivante, ou de d\u00e9couvrir la Path MTU.<\/p>\n\n\n\n<p>Pour s&rsquo;assurer que le serveur TLS est vivant, le client lui envoie une <em>heartbeat request<\/em>. Cette <em>heartbeat request<\/em> consiste en un mot (\u00ab\u00a0cheval\u00a0\u00bb), pr\u00e9c\u00e9d\u00e9 de sa longueur (6, dans notre cas).<\/p>\n\n\n\n<p>Le serveur est cens\u00e9 r\u00e9pondre par une <em>heartbeat response<\/em>, contenant une copie exacte du buffer envoy\u00e9 dans la <em>request<\/em>, en tenant compte de la longueur annonc\u00e9e.<\/p>\n\n\n\n<p>Le coeur de la vuln\u00e9rabilit\u00e9 est que l&rsquo;impl\u00e9mentation OpenSSL ne faisait pas de contr\u00f4le de coh\u00e9rence entre d&rsquo;une part la longueur annonc\u00e9e et la taille r\u00e9elle de la <em>heartbeat request<\/em>.<\/p>\n\n\n\n<p>Ainsi, alors qu&rsquo;une <em>heartbeat request<\/em> l\u00e9gitime est cens\u00e9e avoir cette structure :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+---------+--------+--------+\n| en-t\u00eate | 0x0006 | cheval |\n+---------+--------+--------+\n    fixe     2         6\n&lt;---- 6 octets + cste ------><\/code><\/pre>\n\n\n\n<p>L&rsquo;impl\u00e9mentation OpenSSL ne detectait aucun probl\u00e8me lorsqu&rsquo;elle recevait ceci :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+---------+--------+--------+\n| en-t\u00eate | 0xffff | cheval |\n+---------+--------+--------+\n    fixe     2         6\n&lt;---- 6 octets + cste ------><\/code><\/pre>\n\n\n\n<p>Et retournait 65535 octets dans sa heartbeat response, en lisant dans la m\u00e9moire du serveur au passage !<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Erreur de machine \u00e0 \u00e9tat : EarlyCCS<\/strong><\/h4>\n\n\n\n<p>Cette attaque exploite une erreur dans l&rsquo;impl\u00e9mentation OpenSSL de l&rsquo;automate d&rsquo;\u00e9tat sous-jacent au handshake TLS.<\/p>\n\n\n\n<p>Lorsqu&rsquo;un <code>ChangeCipherSpec<\/code> est envoy\u00e9 au serveur apr\u00e8s l&rsquo;envoi du <code>ServerHello<\/code> et avant la g\u00e9n\u00e9ration du <code>master_secret<\/code>, la d\u00e9rivation des cl\u00e9s de session est r\u00e9alis\u00e9e avec un <code>master_secret<\/code> uniquement constitu\u00e9 de z\u00e9ros, permettant \u00e0 un attaquant de totalement d\u00e9chiffrer le trafic.<\/p>\n\n\n\n<p>Cette vuln\u00e9rabilit\u00e9 touche les versions de OpenSSL ant\u00e9rieures \u00e0 la version 1.0.1h.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Erreur de machine \u00e0 \u00e9tat : Freak<\/strong><\/h4>\n\n\n\n<p>L&rsquo;attaque FREAK, d\u00e9couverte en 2015 (\u00ab\u00a0Factoring Rsa Export Keys\u00a0\u00bb) exploite le support des suites EXPORT et des faiblesses dans l&rsquo;automate d&rsquo;\u00e9tat de certaines impl\u00e9mentations de TLS.<\/p>\n\n\n\n<p>Cette attaque est r\u00e9alisable lorsqu&rsquo;un client supporte ces suites EXPORT et qu&rsquo;un serveur accepte un <code>ClientHello<\/code> proposant une suite EXPORT.<\/p>\n\n\n\n<p>L&rsquo;attaquant remplace \u00e0 la vol\u00e9e le <code>ClientHello<\/code> du client par un <code>ClientHello<\/code> proposant l&rsquo;utilisation d&rsquo;une suite EXPORT.<\/p>\n\n\n\n<p>Le serveur envoie alors une cl\u00e9 RSA de 512 bits, avec laquelle le client chiffre le <code>pre_master_secret<\/code>.<\/p>\n\n\n\n<p>L&rsquo;attaquant, qui a pr\u00e9alablement r\u00e9cup\u00e9r\u00e9 et factoris\u00e9 cette cl\u00e9 (ce qui r\u00e9alisable pour un co\u00fbt tout \u00e0 fait modique aujourd&rsquo;hui) d\u00e9chiffre le <code>pre_master_secret<\/code> et peut d\u00e8s lors r\u00e9aliser la d\u00e9rivation de cl\u00e9s de session, recalculer le message <code>Finished<\/code> et d\u00e9chiffrer le trafic applicatif.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Erreur de machine \u00e0 \u00e9tat : Logjam<\/strong><\/h4>\n\n\n\n<p>L&rsquo;attaque Logjam est au logarithme discret ce que Freak est \u00e0 RSA : un attaquant en position de MitM remplace le <code>ClientHello<\/code> du client par un <code>ClientHello<\/code> proposant l&rsquo;utilisation d&rsquo;une suite DHE_EXPORT.<\/p>\n\n\n\n<p>Finalement, client et serveur r\u00e9alisent un \u00e9change Diffie-Hellman dans un groupe de 512 bits, dans lequel il calculatoirement possible de retrouver le logarithme discret.<\/p>\n\n\n\n<p>L&rsquo;attaquant peut ainsi retrouver le <code>pre_master_secret<\/code>, calculer le message <code>Finished<\/code> et d\u00e9chiffrer le trafic applicatif.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Erreur de machine \u00e0 \u00e9tat : SKIP-TLS<\/strong><\/h4>\n\n\n\n<p>Plusieurs impl\u00e9mentations (JSSE, CyaSSL, OpenSSL\u2026) de TLS autorisent des transitions d&rsquo;\u00e9tat laxistes lors d&rsquo;un handshake.<\/p>\n\n\n\n<p>Par exemple dans JSSE, un attaquant pouvait dropper certains messages, ce qui aboutissait \u00e0 la suite d&rsquo;\u00e9v\u00e9nements suivants :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le client envoie un <code>ClientHello<\/code>,<\/li>\n\n\n\n<li>Le serveur envoie un <code>ServerHello<\/code>,<\/li>\n\n\n\n<li>Le serveur envoie un <code>ServerKeyExchange<\/code>, que l&rsquo;attaquant d\u00e9truit,<\/li>\n\n\n\n<li>Le serveur envoie un <code>ServerHelloDone<\/code>, que l&rsquo;attaquant d\u00e9truit,<\/li>\n\n\n\n<li>Le client envoie un <code>ClientKeyExchange<\/code>, que l&rsquo;attaquant d\u00e9truit,<\/li>\n\n\n\n<li>Le client envoie un <code>ChangeCipherSpec<\/code>, que l&rsquo;attaquant d\u00e9truit,<\/li>\n\n\n\n<li>Le client envoie un <code>Finished<\/code>, que l&rsquo;attaquant d\u00e9truit,<\/li>\n\n\n\n<li>Le serveur envoie un <code>ChangeCipherSpec<\/code>, que l&rsquo;attaquant d\u00e9truit,<\/li>\n\n\n\n<li>Le serveur envoie un <code>Finished<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Ainsi, client et serveur se retrouvent \u00e0 \u00e9changer du trafic applicatif chiffr\u00e9 et authentifi\u00e9 \u00e0 partir de cl\u00e9s de session d\u00e9riv\u00e9es d&rsquo;un <code>pre_master_secret<\/code> nul !<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Sources<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Les diff\u00e9rents articles et sites mentionn\u00e9s tout au long du document<\/li>\n\n\n\n<li>wikipedia !<\/li>\n\n\n\n<li>Conf\u00e9rence de Olivier Levillain \u00e0 l&rsquo;\u00e9dition 2012 du SSTIC (https:\/\/www.sstic.org\/2012\/presentation\/ssl_tls_soa_recos\/)<\/li>\n\n\n\n<li>Conf\u00e9rence de Olivier Levillain \u00e0 l&rsquo;\u00e9dition 2015 du SSTIC (https:\/\/www.sstic.org\/2015\/presentation\/ssltls_soa_reloaded\/)<\/li>\n\n\n\n<li>Une excellente s\u00e9rie de vid\u00e9os sur TLS (https:\/\/www.youtube.com\/@cyrillgossi\/videos)<\/li>\n\n\n\n<li>Le blog https:\/\/blog.cryptographyengineering.com<\/li>\n\n\n\n<li>Le site https:\/\/www.imperialviolet.org<\/li>\n\n\n\n<li>Le site https:\/\/www.mitls.org de l&rsquo;\u00e9quipe \u00e0 l&rsquo;origine des attaques FREAK, Logjam et SKIP-TLS<\/li>\n\n\n\n<li>La RFC 2246 (TLSv1.0)<\/li>\n\n\n\n<li>La RFC 4346 (TLSv1.1)<\/li>\n\n\n\n<li>La RFC 5256 (TLSv1.2)<\/li>\n\n\n\n<li>La RFC 5869 (RFC d\u00e9crivant les fonctions de d\u00e9rivation utilis\u00e9es dans TLSv1.3)<\/li>\n\n\n\n<li>La RFC 6101 (RFC historique d\u00e9crivant SSLv3)<\/li>\n\n\n\n<li>La RFC 6176 (retrait de SSLv2)<\/li>\n\n\n\n<li>La RFC 7366 (extension Encrypt-Then-Mac)<\/li>\n\n\n\n<li>La RFC 7457 (compilant les attaques connues sur SSL\/TLS)<\/li>\n\n\n\n<li>La RFC 7507 (d\u00e9crivant la pseudo-suite de chiffrement SCSV destin\u00e9e \u00e0 d\u00e9tecter les replis de version abusifs)<\/li>\n\n\n\n<li>La RFC 7465 (retrait de RC4)<\/li>\n\n\n\n<li>La RFC 8846 (TLSv1.3)<\/li>\n\n\n\n<li>\u00ab\u00a0A Cryptographic Analysis of the TLS 1.3 Handshake Protocol\u00a0\u00bb, https:\/\/eprint.iacr.org\/2020\/1044.pdf<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>TLS vu d&rsquo;avion TLS (Transport Layer Security) est un protocole cryptographique permettant d&rsquo;\u00e9changer des donn\u00e9es de mani\u00e8re s\u00e9curis\u00e9e au-dessus d&rsquo;une session TCP \u00e9tablie entre un client et un serveur. Les services offerts par TLS sont les suivants : De nombreux protocoles applicatifs pr\u00e9existants ont une variante transport\u00e9e par TLS, faisant de TLS un des piliers [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-360","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts\/360","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/comments?post=360"}],"version-history":[{"count":4,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts\/360\/revisions"}],"predecessor-version":[{"id":364,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts\/360\/revisions\/364"}],"wp:attachment":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/media?parent=360"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/categories?post=360"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/tags?post=360"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}