Aller au contenu
Blockchain Association of Cameroon
BAC-L0-FOUND-1043 h

Fonctions de hachage

Ce qu'une fonction de hachage garantit réellement — résistance aux collisions, effet d'avalanche, déterminisme — et les usages qu'elle ne couvre pas.

  • Énoncer les trois propriétés attendues d'une fonction de hachage cryptographique
  • Calculer et vérifier une empreinte de fichier
  • Expliquer pourquoi hacher n'est pas chiffrer

Une fonction de hachage cryptographique transforme n'importe quelle donnée, d'un mot à un film, en une empreinte de taille fixe — 64 caractères hexadécimaux pour SHA-256 — qui sert d'identifiant du contenu. Cet atelier vous apprend les trois propriétés qu'on en attend (même entrée, même sortie ; un petit changement bouleverse tout ; impossible de fabriquer deux entrées qui donnent la même empreinte), à calculer et vérifier l'empreinte d'un fichier, et à comprendre pourquoi hacher n'est pas chiffrer. C'est la brique qui, un peu plus loin dans le cursus, relie les blocs d'une chaîne, construit les arbres de Merkle et fonde la preuve de travail.

Leçons 1/4 · 25 min

L'empreinte : un condensé de taille fixe

Comment vérifier 700 Mo sans les relire ?

Awa télécharge un logiciel de 700 Mo. Le site indique : « SHA-256 : ba78… ». Comment savoir que le fichier reçu est exactement celui publié, sans le comparer octet par octet avec un original qu'elle n'a pas ? Elle calcule une empreinte (en anglais digest ou hash) du fichier reçu et la compare à l'empreinte publiée : 64 caractères à comparer au lieu de 700 millions d'octets.

Qu'est-ce qu'une fonction de hachage ?

Une fonction de hachage prend des données de n'importe quelle taille (une suite d'octets) et renvoie une valeur de taille fixe. SHA-256, de la famille SHA-2 définie par la norme FIPS 180-4, renvoie toujours 256 bits, soit 32 octets. On les écrit en hexadécimal (base 16 : chiffres 0 à 9 puis lettres a à f), où chaque caractère représente 4 bits : 256 ÷ 4 = 64 caractères.

Entrée (texte, codé en UTF-8)Empreinte SHA-256 (64 caractères hexadécimaux)
(texte vide)e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
abcba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
hello2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Tapez abc dans le widget ci-dessous : vous devez retrouver la deuxième ligne. Un fichier de 700 Mo, lui aussi, donne 64 caractères.

Deux familles de fonctions « de hachage »

À l'atelier 102, la fonction de hachage d'une table sert à répartir des clés dans des cases : il suffit qu'elle soit rapide et bien répartie. Une fonction de hachage cryptographique doit en plus résister à quelqu'un qui cherche activement à la mettre en défaut. On utilise la première pour des structures de données, la seconde pour la sécurité. Quand on dit « hachage » sans précision dans la suite du cursus, on parle de la seconde.

Un piège de débutant : ce qu'on hache vraiment

On hache des octets. Pour un texte, ce sont les octets de son codage (ici UTF-8). Un espace en trop ou un retour à la ligne caché change l'empreinte :

printf 'hello' | sha256sum
# 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

echo hello | sha256sum
# 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03

La seconde commande hache hello suivi d'un retour à la ligne (la commande echo en ajoute un). Ce n'est pas la même donnée, donc pas la même empreinte. Quand deux personnes ne trouvent pas la même empreinte pour « le même texte », c'est presque toujours une différence invisible de ce genre.

À quoi sert une empreinte ?

  • Vérifier l'intégrité d'un fichier téléchargé ou copié (leçon 4).
  • Identifier un contenu par son empreinte : le système de versions Git nomme ainsi chaque objet.
  • S'engager sur une donnée sans la révéler tout de suite : on publie l'empreinte, on dévoile la donnée plus tard.
  • Lier des blocs : chaque bloc contient l'empreinte du précédent (leçon 4, puis les ateliers de blockchain).

Ce que cela ne garantit pas

  • Une empreinte seule ne dit pas qui a produit le fichier : n'importe qui peut calculer le SHA-256 de n'importe quoi. Prouver l'auteur demande une signature (atelier 105).
  • Elle ne cache pas forcément la donnée (leçon 3).
  • Deux fichiers dont les empreintes sont égales sont, en pratique, identiques ; l'inverse « empreintes différentes ⇒ fichiers différents » est, lui, absolument certain.

À retenir

Fonction de hachage : octets de taille quelconque → empreinte de taille fixe (SHA-256 : 256 bits, 64 caractères hexadécimaux). Elle porte sur les octets, au caractère près. L'empreinte identifie un contenu, mais n'en identifie pas l'auteur.

Outil interactif

Empreinte SHA-256

Tapez un texte : l'empreinte se met à jour à chaque caractère. Comparez avec un second texte pour mesurer l'effet d'avalanche.

Empreinte (64 caractères hexadécimaux)

…

Empreinte du second texte

…

Les caractères différents sont soulignés et en gras. Le texte est encodé en UTF-8 sans ajout d'espace ni de retour à la ligne.

Leçons 2/4 · 35 min

Trois propriétés : déterminisme, avalanche, résistance aux collisions

Que doit-on exiger d'une bonne empreinte ?

Imaginons qu'Awa utilise comme empreinte « la somme des codes des lettres, modulo 1 000 ». C'est rapide, de taille fixe… et inutilisable : « AWA » et « AAW » ont la même empreinte (anagrammes), et changer une lettre ne change l'empreinte que de quelques unités. Les trois propriétés ci-dessous sont celles que ce jouet n'a pas.

1. Déterminisme

La même entrée donne toujours la même empreinte, sur toute machine, à tout moment, sans clé secrète. C'est ce qui permet à deux personnes qui ne se connaissent pas de comparer leurs résultats. Le déterminisme s'accompagne d'une sortie de taille fixe (SHA-256 : 256 bits) et d'un calcul rapide : hacher un fichier est presque instantané.

2. Effet d'avalanche

Un changement minuscule de l'entrée — un seul caractère, un seul bit — change l'empreinte de façon imprévisible, comme si elle était entièrement nouvelle. Comparez :

EntréeSHA-256
hello2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Hello185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

Seule la première lettre change (h → H, un seul bit d'écart dans le codage). Pourtant l'empreinte ne ressemble plus à l'autre : en les comparant position par position, 61 des 64 caractères hexadécimaux diffèrent. Ce n'est pas un hasard : si deux chaînes hexadécimales étaient indépendantes, chaque position coïnciderait avec la probabilité 1/16, soit en moyenne 64 ÷ 16 = 4 positions identiques et environ 60 différentes. Voir environ 60 différences, quelle que soit la proximité des entrées, est exactement ce qu'on attend. Cela correspond à environ la moitié des bits : un caractère hexadécimal diffère dès qu'un seul de ses 4 bits diffère, ce qui arrive 15 fois sur 16, alors que chaque bit pris isolément diffère une fois sur deux. Utilisez le widget pour comparer deux textes d'un caractère d'écart et compter les différences.

L'avalanche est un critère de conception, observable à l'œil, qui découle des exigences de sécurité ; il n'est pas à lui seul une preuve de sécurité. Il explique pourtant pourquoi on ne peut pas « s'approcher » d'une empreinte cible par petites retouches successives.

3. Résistance aux collisions (et à ses deux cousines)

Une collision est un couple de deux entrées différentes qui donnent la même empreinte. Les collisions existent forcément : il y a une infinité d'entrées possibles et seulement 2^256 empreintes (principe des tiroirs). La propriété demandée est qu'il soit infaisable de les trouver. Les manuels distinguent trois niveaux, du plus faible au plus exigeant :

PropriétéÉnoncé
Résistance à la préimage (« à sens unique »)Étant donnée une empreinte d, il est infaisable de trouver une entrée m telle que H(m) = d
Résistance à la seconde préimageÉtant donnée une entrée m1, il est infaisable d'en trouver une autre, m2 ≠ m1, avec la même empreinte
Résistance aux collisionsIl est infaisable de trouver n'importe quel couple m1 ≠ m2 de même empreinte

Combien d'essais ? Des ordres de grandeur

Pour SHA-256, retrouver une préimage par essais aveugles demande de l'ordre de 2^256 ≈ 1,2 × 10^77 essais. Pour une collision, le paradoxe des anniversaires montre qu'on en trouve une après environ la racine carrée de ce nombre, soit de l'ordre de 2^128 ≈ 3,4 × 10^38 essais : c'est la meilleure attaque générique connue, et c'est pourquoi on dit que SHA-256 offre environ 128 bits de sécurité contre les collisions. Ces nombres sont hors d'atteinte de tout matériel imaginable.

Pour sentir le principe, tronquons l'empreinte à 16 bits (65 536 valeurs possibles) : par le même raisonnement, une collision apparaît après environ √65 536 = 256 entrées, c'est-à-dire en quelques instants. La longueur de l'empreinte fixe le coût de l'attaque : une empreinte courte est une empreinte cassée.

Ce que cela ne garantit pas

  • « Infaisable » ne veut pas dire « impossible » : c'est un jugement sur l'état actuel du calcul et de la cryptanalyse. Une fonction peut être affaiblie : MD5 et SHA-1 en sont les exemples (leçon 4).
  • À ma connaissance, aucune collision pratique sur SHA-256 n'a été publiée ; cela peut changer, et c'est pourquoi les normes sont revues. Les chiffres ci-dessus valent pour les attaques génériques sur un ordinateur ordinaire ; des ordinateurs quantiques, s'ils existent un jour à grande échelle, réduiraient ces coûts génériques (sans les rendre nuls), et c'est un sujet suivi par les organismes de normalisation.
  • Ces trois propriétés ne couvrent ni le secret ni l'authenticité (leçon 3).

À retenir

Déterminisme : même entrée, même sortie, taille fixe. Avalanche : un petit changement fait diffèrer environ 60 caractères sur 64. Résistance aux collisions : trouver deux entrées de même empreinte est infaisable (environ 2^128 essais pour SHA-256), bien que de telles paires existent.

Outil interactif

Empreinte SHA-256

Tapez un texte : l'empreinte se met à jour à chaque caractère. Comparez avec un second texte pour mesurer l'effet d'avalanche.

Empreinte (64 caractères hexadécimaux)

…

Empreinte du second texte

…

Les caractères différents sont soulignés et en gras. Le texte est encodé en UTF-8 sans ajout d'espace ni de retour à la ligne.

Leçons 3/4 · 30 min

Hacher n'est pas chiffrer

« On a chiffré les codes PIN avec SHA-256 »

Un petit service garde, pour chaque client, l'empreinte SHA-256 de son code PIN à 4 chiffres, et dit : « les codes sont chiffrés, personne ne peut les lire ». Est-ce vrai ? La réponse demande de séparer deux opérations qu'on confond souvent.

Chiffrer et hacher : deux outils différents

ChiffrementHachage
Entréeun message et une clédes octets
Sortieun texte chiffré, de la taille du message environune empreinte de taille fixe
Réversible ?Oui, avec la cléNon, aucune clé, aucun « déchiffrement »
Clé secrète ?OuiNon (la fonction est publique)
Butgarder un contenu secret, puis le retrouveridentifier ou vérifier un contenu

Hacher est à sens unique pour deux raisons qui s'ajoutent. D'abord, la fonction perd de l'information : un fichier de 1 Go donne 32 octets, et d'innombrables entrées donnent la même empreinte, donc « déchiffrer » n'aurait même pas de sens. Cela ne suffit pourtant pas (couper un fichier après ses 32 premiers octets perd aussi de l'information, et se « retrouve » trivialement quand l'entrée est courte). Ensuite, la résistance à la préimage : trouver une entrée qui donne une empreinte donnée est supposé infaisable… à condition de ne pas pouvoir deviner l'entrée.

Le piège des entrées devinables

Un code PIN à 4 chiffres n'a que 10 000 valeurs possibles (0000 à 9999). Un attaquant qui dérobe la base de données calcule le SHA-256 de ces 10 000 candidats et cherche chaque empreinte volée dans sa liste. Ce calcul prend une fraction de seconde sur un ordinateur ordinaire (quelques millisecondes en Python). Le SHA-256 de 1234, par exemple, est 03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4 : n'importe qui peut le calculer et le reconnaître. L'empreinte ne « cache » donc rien : la sécurité d'un secret haché est la sécurité de la difficulté à le deviner. Le PIN n'était pas protégé, il était seulement déguisé.

Mots de passe : il faut un hachage fait pour cela

Un bon hachage de mots de passe doit être lent exprès et salé :

  • le sel (salt) est une valeur aléatoire propre à chaque utilisateur, stockée à côté de l'empreinte et mélangée au mot de passe avant le hachage. Deux utilisateurs avec le même mot de passe ont alors des empreintes différentes, et les tables d'empreintes précalculées deviennent inutiles ;
  • une fonction volontairement lente (Argon2, scrypt, bcrypt, PBKDF2 ; Argon2 et scrypt exigent en plus beaucoup de mémoire) rend chaque essai de l'attaquant coûteux. SHA-256 simple, conçu pour être rapide, est un mauvais choix ici.

Aucune de ces précautions n'est « du chiffrement » : le mot de passe n'est jamais récupéré, seulement comparé.

Prouver qui a produit un message : HMAC

Une empreinte seule ne prouve pas l'auteur : l'attaquant peut modifier le message et recalculer l'empreinte. Un HMAC mélange une clé secrète partagée au message avant le hachage : seule une personne qui connaît la clé peut produire l'HMAC correct. Le widget ci-dessous calcule un HMAC-SHA256 : essayez-le avec une clé fictive (par exemple cle-fictive-de-demonstration), puis changez un caractère du message ou de la clé et observez que l'HMAC change entièrement. Avec un HMAC, celui qui vérifie doit connaître la même clé que celui qui produit : la preuve est donc partagée entre deux personnes, pas publique. Les signatures de l'atelier 105 apporteront une preuve vérifiable par tous.

Ce que cela ne garantit pas

  • Hacher ne cache pas une donnée devinable (PIN, prénom, numéro de téléphone) : l'attaquant essaie toutes les possibilités.
  • Une empreinte égale révèle que deux données sont égales : c'est utile (détecter un doublon) mais c'est aussi une fuite.
  • Une empreinte ne prouve pas l'origine : n'importe qui peut hacher n'importe quoi.

À retenir

Chiffrer = réversible avec une clé ; hacher = sans clé, à sens unique, taille fixe. Un secret haché n'est protégé que par la difficulté de le deviner : les PIN et mots de passe demandent un hachage lent et salé. HMAC ajoute une clé pour authentifier un message entre deux personnes qui la partagent.

Outil interactif

Empreinte SHA-256

Tapez un texte : l'empreinte se met à jour à chaque caractère. Comparez avec un second texte pour mesurer l'effet d'avalanche.

Empreinte (64 caractères hexadécimaux)

…

Empreinte du second texte

…

Les caractères différents sont soulignés et en gras. Le texte est encodé en UTF-8 sans ajout d'espace ni de retour à la ligne.

Outil interactif

HMAC

Code d'authentification de message : une empreinte qui dépend d'un secret partagé. Sans la clé, impossible de la recalculer.

Format de clé
Format de message

HMAC (hexadécimal)

…

Une clé vide est acceptée (elle équivaut à une clé de zéros).

Leçons 4/4 · 35 min

Vérifier un fichier, puis enchaîner des blocs

Vérifier une empreinte de fichier

Sur Linux et macOS : sha256sum fichier (ou shasum -a 256 fichier). Sous Windows, dans PowerShell : Get-FileHash fichier -Algorithm SHA256. En Python :

import hashlib

def sha256_file(path):
    h = hashlib.sha256()
    with open(path, "rb") as f:
        for chunk in iter(lambda: f.read(65536), b""):
            h.update(chunk)
    return h.hexdigest()

On lit par morceaux pour ne pas charger 700 Mo en mémoire ; l'empreinte finale est la même que si l'on avait lu tout d'un coup. Les projets publient souvent un fichier d'empreintes dont chaque ligne est « empreinte, deux espaces, nom du fichier », que sha256sum -c vérifie automatiquement.

Lire le résultat. Les deux empreintes sont identiques au caractère près, ou elles ne le sont pas : il n'y a pas de « presque identique ». Une seule différence — même au dernier caractère — signifie que le fichier n'est pas celui qui a été publié. Cela peut être une corruption (téléchargement interrompu) ou une altération volontaire ; dans les deux cas, ne l'exécutez pas.

D'où vient l'empreinte de référence ?

Vérifier suppose que l'on fait confiance à l'empreinte publiée. Si le fichier et l'empreinte viennent du même serveur compromis, l'attaquant remplace les deux et la vérification réussit. L'empreinte protège donc contre la corruption accidentelle et contre un fichier altéré lorsque l'empreinte a été obtenue par un canal distinct et fiable (autre site officiel, annonce signée). Pour une preuve qui tienne même si le serveur est compromis, il faut une signature numérique (atelier 105).

Enchaîner des blocs par leurs empreintes

L'atelier 103 s'est terminé sur un problème : modifier une ligne du journal ne laissait aucune trace. Voici l'idée qui le résout. Chaque bloc contient ses données et l'empreinte du bloc précédent ; son empreinte à lui est calculée sur le tout. Notre chaîne JOUET, avec la convention « numéro | données | empreinte précédente » :

bloc 1 : 1|Awa credit 100|GENESIS
         empreinte h1 = fa68461319a4bcab4ea332b39bc1d03311f222f813c36432235756047f20c312

bloc 2 : 2|Awa pays Kofi 30|fa68461319a4bcab4ea332b39bc1d03311f222f813c36432235756047f20c312
         empreinte h2 = fdec2cc6e9c9c0997020c1acc3b3f044ab80cb6fd5a963da3881ac1c035523bd

bloc 3 : 3|Kofi pays Mba 10|fdec2cc6e9c9c0997020c1acc3b3f044ab80cb6fd5a963da3881ac1c035523bd
         empreinte h3 = eff5f1c07e8133f22ba376f95f24d1692dbcb842b23746824cc84afd1cb10575

Vous pouvez recalculer h1 en tapant exactement 1|Awa credit 100|GENESIS dans le widget sha256.

L'attaque. Un fraudeur change, dans le bloc 2, « 30 » en « 300 ». L'empreinte du bloc 2 devient 2f359f87ad0dcc90… au lieu de fdec2cc6e9c9c099…. Or le bloc 3 contient toujours l'ancienne empreinte (fdec2cc6…) : en recalculant, la vérification constate que l'empreinte du bloc 2 ne correspond plus à ce que le bloc 3 annonce. L'altération est détectée.

Pour la cacher, le fraudeur doit corriger le bloc 3 (il y met 2f359f87…), ce qui change l'empreinte du bloc 3, donc il doit corriger le bloc 4, et ainsi de suite jusqu'à la fin de la chaîne. Dans une chaîne de n blocs où l'on modifie le bloc k, il faut recalculer tous les blocs de k + 1 à n. Et si quelqu'un d'autre a gardé une copie de la dernière empreinte, la chaîne réécrite ne correspondra plus à cette copie. Le widget « chain-explorer » vous laisse modifier un bloc et voir se briser les empreintes suivantes.

L'avertissement honnête

  • Le chaînage détecte une modification ; il ne l'empêche pas. Si personne ne conserve ailleurs la dernière empreinte, un fraudeur qui contrôle toute la chaîne peut la réécrire entièrement, proprement. Que plusieurs acteurs indépendants gardent la même chaîne est l'objet de l'atelier sur le consensus.
  • Il ne dit pas qui a écrit un bloc, ni que son contenu est vrai : il garantit seulement que le contenu n'a pas changé depuis que l'empreinte a été calculée.
  • Notre convention de chaîne est un jouet. Les vraies chaînes ont un format précis (en-têtes d'octets, double hachage dans Bitcoin), que vous verrez plus tard.

MD5 et SHA-1 : pourquoi on les proscrit

Des collisions pratiques ont été publiées pour MD5 (dans les années 2000) et pour SHA-1 (première collision publique en 2017). Ces fonctions ne remplissent donc plus la résistance aux collisions, et on ne les utilise plus pour des signatures ou des certificats. MD5 reste correct pour détecter une corruption accidentelle, mais pas face à un adversaire. Voir l'exercice de sécurité.

À retenir

Vérifier un fichier = calculer son empreinte et la comparer, caractère par caractère, à une référence obtenue par un canal fiable. Chaîner des blocs par leurs empreintes rend toute modification détectable et oblige à recalculer tous les blocs suivants, sans la rendre impossible.

Outil interactif

Empreinte SHA-256

Tapez un texte : l'empreinte se met à jour à chaque caractère. Comparez avec un second texte pour mesurer l'effet d'avalanche.

Empreinte (64 caractères hexadécimaux)

…

Empreinte du second texte

…

Les caractères différents sont soulignés et en gras. Le texte est encodé en UTF-8 sans ajout d'espace ni de retour à la ligne.

Outil interactif

Explorateur de chaîne de blocs (jouet)

Cinq blocs liés par leur empreinte. Modifiez les données d'un bloc : son empreinte change, le lien du suivant se rompt, et tous les blocs suivants deviennent invalides.

Construction de la chaîne (minage des 5 blocs)…

Ceci est un jouet. L'empreinte d'un bloc est SHA-256 de « index|empreinte précédente|données|nonce » ; la difficulté est de seulement deux zéros hexadécimaux au début (environ 256 essais). Une vraie chaîne exige un travail astronomiquement plus grand et un réseau de nœuds qui vérifient chacun la chaîne.

Laboratoire guidé

Le calcul des empreintes se fait ici avec le widget sha256 de la page ; la vérification d'un binaire téléchargé avec sha256sum et la chaîne jouet en Python forment le laboratoire autonome. Les épreuves générées vous donnent un texte différent à chaque tentative : il faut vraiment calculer. Les autres étapes sont des questions de raisonnement sur les empreintes que vous venez d'observer.

Le navigateur ne remplace pas un vrai terminal : ce laboratoire entraîne la lecture et le raisonnement ; la pratique réelle est dans le laboratoire autonome.

Un compte certifié est nécessaire

Les activités notées enregistrent des résultats à votre nom et servent de base à un titre. Elles exigent donc un dossier certifiant complet et un consentement en vigueur. Remplir le dossier ne vérifie pas votre identité ; le Secrétariat peut ensuite la vérifier (badge « Vérifié »).

  1. 1.Calculer une empreinte

    L'épreuve ci-dessous donne un court texte. Saisissez-le dans le widget sha256 exactement, caractère pour caractère, sans espace ni retour à la ligne en plus ni en moins, puis recopiez l'empreinte de 64 caractères dans le champ de réponse. Si votre résultat est refusé, relisez le texte : un tiret, un chiffre ou une majuscule mal copiés suffisent à changer toute l'empreinte, comme vous l'avez vu dans la leçon 2.

    Outil interactif

    Empreinte SHA-256

    Tapez un texte : l'empreinte se met à jour à chaque caractère. Comparez avec un second texte pour mesurer l'effet d'avalanche.

    Empreinte (64 caractères hexadécimaux)

    …

    Empreinte du second texte

    …

    Les caractères différents sont soulignés et en gras. Le texte est encodé en UTF-8 sans ajout d'espace ni de retour à la ligne.

  2. 2.Mesurer l'effet d'avalanche

    L'épreuve donne deux messages A et B qui ne diffèrent que par leur dernier caractère. Hachez-les tous les deux avec le widget, recopiez les 16 premiers caractères de chaque empreinte, puis comptez sur combien des 64 positions hexadécimales les deux empreintes diffèrent (le widget de comparaison compte les différences pour vous ; vérifiez qu'il donne un nombre proche de 60). Avant de calculer, notez votre prédiction : combien de positions pensez-vous trouver différentes ?

    Outil interactif

    Empreinte SHA-256

    Tapez un texte : l'empreinte se met à jour à chaque caractère. Comparez avec un second texte pour mesurer l'effet d'avalanche.

    Empreinte (64 caractères hexadécimaux)

    …

    Empreinte du second texte

    …

    Les caractères différents sont soulignés et en gras. Le texte est encodé en UTF-8 sans ajout d'espace ni de retour à la ligne.

  3. 3.Verdict sur un téléchargement

    Un projet publie l'empreinte attendue de son installateur, obtenue sur une page officielle, puis vous calculez celle du fichier reçu (supposez que vous avez recopié les deux à la main, sans erreur de lecture de votre part) :

    publiée : 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
    calculée: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9825

    Comparez-les caractère par caractère (63 caractères sur 64 sont identiques, mais ce n'est pas la question), puis répondez à la question posée : que concluez-vous, et que faites-vous du fichier ? Appuyez-vous sur la leçon 4 pour ce qu'une différence signifie.

  4. 4.Casser un code PIN « haché »

    Le service de la leçon 3 stocke SHA-256(PIN) pour chaque code PIN à 4 chiffres. Vous volez un enregistrement. Décrivez en trois lignes votre méthode d'attaque : quels candidats, quel calcul, comment reconnaître le bon. Puis répondez à la question posée : au maximum, combien d'empreintes devez-vous calculer pour être certain de retrouver n'importe quel code ? Avec le widget sha256, vérifiez que l'empreinte de 1234 est bien celle donnée en leçon 3.

  5. 5.Réécrire une chaîne

    Ouvrez le widget de chaîne de cinq blocs. Modifiez les données du bloc 2 et observez quelles empreintes changent, puis utilisez « Re-miner à partir d'ici » pour retrouver une chaîne cohérente. Attention : la chaîne de ce widget ajoute à chaque bloc un nombre appelé nonce et exige une empreinte commençant par 00 ; c'est une règle de preuve de travail que l'atelier 110 expliquera, et sa formule d'empreinte (« numéro|empreinte précédente|données|nonce ») n'est pas celle de la leçon 4. Pour cet atelier, observez seulement quelles empreintes changent et quels blocs doivent être recalculés. Notez combien de blocs, en plus du bloc 2, ont dû être recalculés. Remettez ensuite le bloc 2 d'origine, modifiez le bloc 4 et refaites le même relevé. Puis répondez à la question posée, qui porte sur une chaîne plus longue que celle du widget.

    Outil interactif

    Explorateur de chaîne de blocs (jouet)

    Cinq blocs liés par leur empreinte. Modifiez les données d'un bloc : son empreinte change, le lien du suivant se rompt, et tous les blocs suivants deviennent invalides.

    Construction de la chaîne (minage des 5 blocs)…

    Ceci est un jouet. L'empreinte d'un bloc est SHA-256 de « index|empreinte précédente|données|nonce » ; la difficulté est de seulement deux zéros hexadécimaux au début (environ 256 essais). Une vraie chaîne exige un travail astronomiquement plus grand et un réseau de nœuds qui vérifient chacun la chaîne.

Exercice de sécurité — Collision volontaire : ce qu'elle permet à un attaquant

Un service qui approuve des paiements « par empreinte »

Une petite entreprise a mis en place une règle : un ordre de paiement est approuvé par le directeur, qui enregistre non pas le texte de l'ordre mais son empreinte. Plus tard, le service comptable n'exécute que les ordres dont l'empreinte correspond à celle qui a été approuvée. Pour faire simple et peu coûteux, l'entreprise a choisi une fonction JOUET : la somme des codes des caractères du texte, modulo 1 000. (C'est un jouet de classe, pas un vrai algorithme.)

L'ordre soumis à l'approbation est : PAY 001 TO KOFI (payer 1 franc à Kofi). Le directeur approuve l'empreinte qui lui est présentée : 935. Le fraudeur, lui, a déposé l'ordre au nom d'un faux client et espère le remplacer, après approbation, par un ordre qui donne la même empreinte 935.

Calculez : la somme des codes des caractères de PAY 001 TO KOFI (P = 80, A = 65, Y = 89, espace = 32, 0 = 48, 0 = 48, 1 = 49, espace = 32, T = 84, O = 79, espace = 32, K = 75, O = 79, F = 70, I = 73) est 935, et 935 mod 1 000 = 935.

Pourquoi ce jouet ne résiste pas

La somme ne dépend ni de l'ordre ni de la position des caractères : toute permutation du texte garde la même empreinte. L'attaque n'exige aucune puissance de calcul. Avec une vraie fonction de hachage cryptographique, changer un caractère ou en permuter deux bouleverse l'empreinte (avalanche), et trouver deux ordres de même empreinte demande environ 2^128 essais.

Les vraies collisions, avec honnêteté

Avec MD5 et SHA-1, on a bien publié des méthodes qui construisent des collisions pratiques. Elles ne permettent pas de « fabriquer un document qui a la même empreinte qu'un document existant imposé » (ce serait une attaque de seconde préimage, toujours infaisable) : l'attaquant doit préparer lui-même les deux documents avant que l'un d'eux soit approuvé, signé ou publié. C'est exactement le scénario ci-dessus : l'attaquant propose, fait approuver ou signer le document inoffensif, puis fait circuler l'autre. C'est pourquoi on ne signe plus avec ces fonctions.

À faire

Répondez à la question de contrôle : parmi les ordres proposés, lesquels donnent la même empreinte jouet, 935, que PAY 001 TO KOFI ?

Questionnaire de l'atelier

Huit questions tirées d'une réserve plus large, seuil de réussite 70 %. Il s'ouvre quand tous les points de contrôle du laboratoire sont réussis. Vous pouvez le repasser : le tirage change.

Un compte certifié est nécessaire

Les activités notées enregistrent des résultats à votre nom et servent de base à un titre. Elles exigent donc un dossier certifiant complet et un consentement en vigueur. Remplir le dossier ne vérifie pas votre identité ; le Secrétariat peut ensuite la vérifier (badge « Vérifié »).

Laboratoire autonome (hors du site)

Non noté en ligne : à réaliser sur votre machine et à publier sur votre dépôt Git.

Laboratoire autonome : vérifier un binaire, puis construire une chaîne jouet

À faire sur votre machine (Linux, macOS ou WSL), avec Python 3 et hashlib (aucune installation).

Partie 1 : vérifier un téléchargement. Choisissez un petit logiciel libre dont le projet publie une empreinte SHA-256 par un canal officiel (page de téléchargement, annonce de version). Téléchargez le fichier, puis calculez son empreinte avec sha256sum (ou shasum -a 256) et comparez-la à celle du projet, caractère par caractère. Notez d'où vient votre empreinte de référence et ce que cette vérification ne couvre pas si le site est compromis. Puis changez un seul octet d'une copie du fichier (avec un éditeur hexadécimal ou un petit script) et recalculez : constatez l'avalanche.

Partie 2 : l'empreinte d'un fichier en Python. Écrivez sha256_file(path) (voir leçon 4, lecture par morceaux) et vérifiez que son résultat égale celui de sha256sum sur trois fichiers dont un de plus de 10 Mo.

Partie 3 : la chaîne jouet. Écrivez une classe ou des fonctions pour des blocs (index, data, prev_hash) dont l'empreinte est le SHA-256 de la chaîne "index|data|prev_hash" (le premier bloc utilise prev_hash = "GENESIS"). Ajoutez append_block(chain, data) et verify(chain) qui recalcule chaque empreinte et vérifie chaque lien. Écrivez les tests : une chaîne valide de dix blocs passe ; modifier les données du bloc 4 fait échouer verify en indiquant le bon bloc ; modifier le bloc 4 puis recalculer en cascade les blocs 5 à 10 produit une chaîne qui passe verify mais dont la dernière empreinte a changé (c'est ce que détecterait quelqu'un qui avait gardé l'ancienne).

Partie 4 : dire ce que le jouet ne fait pas. Dans une courte note, listez trois choses que votre chaîne ne garantit pas (auteur du bloc, vérité des données, unicité de la chaîne) et reliez chacune à un atelier du cursus qui la traitera.

À rendre. Le code, les tests, la preuve de la partie 1 (les deux empreintes comparées, l'URL du canal de référence) et la note. La chaîne doit être vérifiable par quelqu'un d'autre sans vos explications : documentez le format exact des blocs.

À retenir

  • Une fonction de hachage cryptographique transforme n'importe quelle donnée en empreinte de taille fixe (SHA-256 : 256 bits, 64 caractères hexadécimaux) ; elle porte sur des octets, au caractère près.
  • Trois propriétés : déterminisme (même entrée, même sortie), avalanche (un petit changement fait diffèrer environ 60 caractères sur 64) et résistance aux collisions (trouver deux entrées de même empreinte est infaisable, bien que de telles paires existent).
  • Vérifier un fichier, c'est comparer son empreinte, caractère par caractère, à une référence obtenue par un canal fiable ; cela ne prouve ni l'auteur ni la bonne foi du fichier.
  • Hacher n'est pas chiffrer : pas de clé, pas de retour en arrière. Un secret haché n'est protégé que par la difficulté de le deviner ; PIN et mots de passe demandent un hachage lent et salé.
  • Enchaîner des blocs par leurs empreintes rend toute modification détectable et force à recalculer les blocs suivants, sans l'empêcher ; MD5 et SHA-1 ne sont plus sûrs face à un adversaire.

Idées fausses courantes

  • Idée reçue : Une empreinte, c'est une version chiffrée du fichier : on peut la déchiffrer avec la bonne clé.

    En réalité : Il n'y a ni clé ni déchiffrement. La fonction est publique et à sens unique : un fichier de 1 Go donne 32 octets, dont on ne peut pas reconstruire le fichier.

  • Idée reçue : Si deux entrées différentes donnaient la même empreinte, la fonction serait forcément cassée : les collisions n'existent pas.

    En réalité : Les collisions existent toujours (infinité d'entrées, 2^256 sorties). Une bonne fonction est celle pour laquelle les trouver est infaisable.

  • Idée reçue : Hacher un PIN ou un mot de passe avec SHA-256 suffit à le protéger.

    En réalité : Si l'entrée est devinable, l'attaquant essaie toutes les possibilités (10 000 pour un PIN à 4 chiffres, en une fraction de seconde). Il faut un hachage lent et salé.

  • Idée reçue : Si l'empreinte du fichier correspond à celle du site, le fichier est sûr.

    En réalité : Cela prouve seulement que le fichier est celui dont on a publié l'empreinte. Si le site est compromis, l'attaquant change les deux ; il faut une référence par un canal distinct ou une signature.

Glossaire

Fonction de hachage
Fonction qui transforme des données de taille quelconque en une valeur de taille fixe (l'empreinte) ; déterministe et publique.
Empreinte (digest)
Résultat d'une fonction de hachage ; pour SHA-256, 32 octets, écrits en 64 caractères hexadécimaux.
SHA-256
Fonction de hachage de la famille SHA-2 (norme FIPS 180-4) qui produit une empreinte de 256 bits.
Effet d'avalanche
Propriété selon laquelle un petit changement de l'entrée modifie environ la moitié des bits de l'empreinte, de façon imprévisible.
Collision
Deux entrées différentes qui donnent la même empreinte. Elles existent toujours ; la sécurité repose sur l'impossibilité pratique d'en trouver.
Résistance à la préimage
Étant donnée une empreinte, il est infaisable de retrouver une entrée qui la produit (propriété « à sens unique »).
Sel (salt)
Valeur aléatoire propre à chaque utilisateur, mélangée au mot de passe avant hachage pour que deux mots de passe identiques donnent des empreintes différentes.
HMAC
Empreinte calculée avec une clé secrète partagée, qui permet de vérifier qu'un message vient d'un détenteur de la clé et n'a pas été modifié.
Hexadécimal
Écriture en base 16 (0-9, a-f) où chaque caractère représente 4 bits.
Chaînage par empreintes
Technique où chaque bloc contient l'empreinte du précédent, ce qui rend toute modification d'un bloc détectable dans les suivants.