MD5, SHA-1 ou SHA-256 : quel algorithme de hachage choisir ?

Choisissez SHA-256 pour tout ce qui touche à la sécurité. MD5 et SHA-1 ne sont acceptables que là où personne n'a rien à gagner à forger une empreinte identique.

MD5, SHA-1 et SHA-256 font tous le même travail : ils transforment une entrée de n'importe quelle longueur en une empreinte courte et de taille fixe, appelée digest. La même entrée donne toujours la même empreinte, et la modification d'un seul bit change tout le résultat. Les trois se distinguent par la longueur de l'empreinte, par leur vitesse et surtout sur un point : peut-on produire délibérément deux entrées différentes qui ont la même empreinte ? Pour MD5 et SHA-1, cela a été fait publiquement. Pour SHA-256, non.

Les trois algorithmes en un coup d'œil

MD5SHA-1SHA-256
Taille de l'empreinte128 bits, 32 caractères hexadécimaux160 bits, 40 caractères hexadécimaux256 bits, 64 caractères hexadécimaux
Publication1992 (RFC 1321)1995 (FIPS 180-1)2001, au sein de la famille SHA-2
CollisionsRéalisables en pratique depuis 2004Réalisables en pratique depuis 2017Aucune attaque connue
Retrouver une entrée à partir d'une empreinte donnéeAucune attaque pratiqueAucune attaque pratiqueAucune attaque pratique
Usage conseillé aujourd'huiChecksums sans enjeu de sécurité, clés de cacheCompatibilité avec l'existant uniquementLe choix par défaut pour tout nouveau projet

Voici les empreintes complètes des cinq octets hello, telles que les affichent md5sum, sha1sum et sha256sum. Le générateur de hash présente ces mêmes valeurs côte à côte, avec en plus SHA-384 et SHA-512, pour un texte ou pour un fichier jusqu'à 50 Mo.

MD5      5d41402abc4b2a76b9719d911017c592
SHA-1    aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
SHA-256  2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Ce que les bits supplémentaires apportent

La longueur de l'empreinte fixe le coût d'une attaque générique, c'est-à-dire une attaque qui traite la fonction comme une boîte noire. À cause du paradoxe des anniversaires, trouver deux entrées quelconques qui entrent en collision demande environ 2^(n/2) essais pour une empreinte de n bits : 2^64 pour MD5, 2^80 pour SHA-1 et 2^128 pour SHA-256. Trouver une entrée qui correspond à une empreinte précise (une préimage) demande environ 2^n essais.

Ces chiffres ne tiennent que tant que la conception de l'algorithme n'offre aucun raccourci. MD5 et SHA-1 ont tous deux des raccourcis pour les collisions : leur longueur ne dit donc plus tout. SHA-256 n'a aucun raccourci connu, et 2^128 dépasse de très loin toute la puissance de calcul qui existe.

Comment MD5 et SHA-1 ont été cassés

Une attaque par collision ne permet à personne d'inverser un hash. Elle permet à un attaquant de préparer à l'avance deux entrées différentes qui partagent la même empreinte, de faire accepter l'une comme digne de confiance, puis de lui substituer l'autre. La variante dangereuse est la collision à préfixe choisi (chosen-prefix) : l'attaquant choisit deux débuts qui ont un sens, par exemple deux certificats portant des noms différents, puis calcule des octets supplémentaires qui rendent les empreintes identiques.

  • MD5, 2004 : Xiaoyun Wang et ses collègues publient des collisions MD5 réalisables en pratique.
  • MD5, 2008 : une équipe de chercheurs exploite une collision MD5 à préfixe choisi pour créer un faux certificat d'autorité de certification que les navigateurs auraient accepté, parce qu'une autorité de certification commerciale signait encore ses certificats avec MD5.
  • MD5, 2012 : le malware Flame utilise une collision MD5 pour forger un certificat de signature de code Microsoft.
  • SHA-1, 2017 : Google et le CWI Amsterdam annoncent SHAttered, deux fichiers PDF différents ayant la même empreinte SHA-1. L'équipe indique environ 6 500 années-CPU et 110 années-GPU de calcul.
  • SHA-1, 2020 : Gaëtan Leurent et Thomas Peyrin publient une collision SHA-1 à préfixe choisi réalisable en pratique et s'en servent pour usurper une clé PGP.

Les navigateurs ont cessé d'accepter les certificats TLS en SHA-1 en 2017, et le NIST a annoncé en décembre 2022 que SHA-1 devait être complètement abandonné d'ici fin 2030. Ni MD5 ni SHA-1 ne connaît d'attaque pratique par préimage : à partir d'une empreinte seule, personne ne sait retrouver une entrée qui la produit. C'est pourquoi les deux restent efficaces pour détecter des dommages accidentels.

Vitesse : mesurée, pas supposée

On présente souvent MD5 comme l'algorithme rapide. Nous avons haché les mêmes 256 Mo de données aléatoires avec Node 24 (OpenSSL 3.5) sur un seul ordinateur de bureau, trois fois pour chaque algorithme :

AlgorithmeDébit sur cette machine
SHA-1environ 1 000 Mo/s
MD5environ 730 Mo/s
SHA-512environ 690 Mo/s
SHA-256environ 460 Mo/s

L'ordre dépend du processeur. Ce CPU ne dispose pas des extensions du jeu d'instructions SHA. Les processeurs qui en sont équipés accélèrent SHA-1 et SHA-256 au niveau matériel, et SHA-256 peut alors dépasser MD5. SHA-512 a battu SHA-256 ici parce qu'il travaille sur des mots de 64 bits. Sur des entrées courtes, l'écart disparaît : un million de hashs d'une courte adresse e-mail ont pris entre 1,8 et 2,1 secondes, que ce soit avec MD5, SHA-1 ou SHA-256, car le coût fixe de chaque appel pèse plus lourd que le hachage lui-même. La vitesse n'est presque jamais une vraie raison de choisir MD5.

Ce à quoi chacun sert encore

  • MD5 : détecter une corruption accidentelle, dédupliquer vos propres fichiers, produire des clés de cache et des ETag, dialoguer avec des systèmes anciens qui l'exigent. Jamais pour des signatures, des certificats ou des contrôles d'intégrité lorsqu'un attaquant pourrait fournir le fichier.
  • SHA-1 : les systèmes existants que vous ne pouvez pas encore modifier. Git nomme depuis longtemps ses objets avec SHA-1, à l'aide d'une implémentation renforcée qui détecte les attaques par collision connues, et prend aussi en charge des dépôts en SHA-256. HMAC-SHA1, l'algorithme par défaut derrière les codes TOTP des applications d'authentification, n'est pas concerné par les attaques par collision.
  • SHA-256 : checksums de téléchargement, signatures numériques, certificats, HMAC, adressage par contenu et tout nouveau projet. Utilisez SHA-256 lorsqu'un checksum doit résister à une falsification, et réservez MD5 aux anciennes valeurs que vous devez encore retrouver.

Vous vérifiez un téléchargement ? Le vérificateur de checksum de fichier calcule le hash du fichier en local et vous indique à quel algorithme correspond le checksum que vous avez collé.

Aucun des trois ne doit stocker des mots de passe

Tous trois sont conçus pour être rapides, et la rapidité est précisément ce que recherche un attaquant qui essaie des milliards de mots de passe. Un sel empêche l'usage de tables précalculées, mais il ne ralentit pas les essais. Le stockage des mots de passe exige une fonction volontairement lente et, idéalement, gourmande en mémoire (memory-hard). Sur la même machine que ci-dessus :

Fonction et paramètresTemps par mot de passe
SHA-256, un appel depuis Nodeenviron 2,5 microsecondes
Argon2id, 19 Mio de mémoire, 2 itérations, 1 voie (lane)environ 33 millisecondes
PBKDF2-HMAC-SHA256, 600 000 itérationsenviron 270 millisecondes
scrypt, N=2^17, r=8, p=1environ 310 millisecondes

Ces paramètres sont les minimums indiqués par l'OWASP Password Storage Cheat Sheet, qui recommande d'abord Argon2id, puis scrypt, bcrypt avec un facteur de coût de 10 ou plus pour les systèmes existants, et PBKDF2 lorsque la conformité FIPS-140 est exigée. Utilisez l'API de hachage de mots de passe de votre framework plutôt que d'en assembler une à partir d'un simple hash.

HMAC : quand un hash a besoin d'une clé

Pour prouver qu'un message provient de quelqu'un qui détient un secret, ne calculez pas sha256(secret + message). MD5, SHA-1 et SHA-256 sont tous exposés à l'extension de longueur (length extension) : connaître l'empreinte d'un message permet à un attaquant de calculer une empreinte valide pour ce message suivi de données supplémentaires, sans connaître le secret. HMAC (RFC 2104) évite ce problème. HMAC-SHA256 est le choix standard, et toutes ces lignes affichent la même valeur :

// Node.js
crypto.createHmac('sha256', 'secret').update('hello').digest('hex')

# Python
hmac.new(b'secret', b'hello', hashlib.sha256).hexdigest()

// PHP
hash_hmac('sha256', 'hello', 'secret')

// 88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b

Comparez les HMAC avec une fonction à temps constant comme crypto.timingSafeEqual, hmac.compare_digest ou hash_equals, et non avec ==.

Calculer un hash en ligne de commande et dans le code

# Linux (coreutils)
md5sum file.iso
sha1sum file.iso
sha256sum file.iso

# macOS
md5 file.iso
shasum -a 1 file.iso
shasum -a 256 file.iso

# Windows PowerShell
Get-FileHash file.iso -Algorithm MD5
Get-FileHash file.iso -Algorithm SHA1
Get-FileHash file.iso              # SHA256 is the default

# Any system with OpenSSL
openssl dgst -sha256 file.iso

# Hashing a string: printf adds no newline, echo does
printf '%s' hello | sha256sum      # 2cf24dba5fb0a30e...
echo hello | sha256sum             # 5891b5b522d5df08...

Dans le navigateur, crypto.subtle.digest() prend en charge SHA-1, SHA-256, SHA-384 et SHA-512, mais pas MD5 : lui demander MD5 lève une NotSupportedError. C'est pourquoi les outils qui tournent dans le navigateur, y compris ceux de ce site, calculent MD5 avec une implémentation JavaScript distincte.

Questions Fréquentes

SHA-256 est-il plus lent que MD5 ?

Cela dépend du processeur. Sur un processeur sans extensions SHA, nous avons mesuré environ 730 Mo/s pour MD5 et 460 Mo/s pour SHA-256. Les processeurs dotés des extensions SHA accélèrent assez SHA-256 pour qu'il puisse dépasser MD5, et sur des chaînes courtes la différence est négligeable.

MD5 convient-il encore pour les checksums de fichiers ?

Pour repérer une corruption accidentelle, oui, car personne ne sait trouver un fichier qui corresponde à une empreinte MD5 donnée. Non lorsqu'un attaquant a pu préparer le fichier, car les collisions MD5 ne coûtent presque rien. Utilisez SHA-256 quand le checksum doit résister à une falsification.

SHA-1 est-il cassé ?

Sa résistance aux collisions l'est. Des collisions pratiques ont été démontrées en 2017, puis des collisions à préfixe choisi en 2020 : SHA-1 ne doit donc plus servir pour des signatures ou des certificats. HMAC-SHA1 et la résistance aux préimages ne sont pas touchés par ces attaques, mais les nouveaux systèmes doivent utiliser SHA-256.

Quel hash utiliser pour les mots de passe ?

Aucun de ces trois. Utilisez Argon2id, ou bien scrypt ou bcrypt si Argon2id n'est pas disponible. Ces fonctions sont volontairement lentes et salées, ce qui rend bien plus coûteuse la recherche des mots de passe à partir d'une base de données volée.