PHP : Comparaison MD5 / SHA-1

Allez, ça faisait bien longtemps que je n’avais pas pris le temps d’écrire un article orienté technique. Celui-là sera assez court mais j’espère qu’il vous conviendra car on trouve difficilement l’information sur le net. Voici donc un petit bench rapide entre deux algorithmes de hachage très souvent utilisés en PHP : MD5 et SHA1

Présentation algorithmes de hashage

Ces deux algorithmes de hachage (il en existe d’autres) permettent de calculer l’empreinte d’une chaine de caractère de façon à en cacher son contenu.
MD5('loicmorvan.fr') = 53a021aa58fe4ace1d1dcaa3cd94ef59
SHA1('loicmorvan.fr') = d746fa906c2e6da62ab3690cc4115d5f4dca5a50

De manière générale, ses algorithmes ne sont pas réversibles. J’en entends déjà certains d’entre vous crier au scandale ou se demander comment ils vont vérifier un mot de passe. Simple ! Vous vérifiez que les hashs correspondent : par exemple, vous vérifiez que :

md5(mot_de_passe_recu) = mot_de_passe_en_base_deja_hashe_avec_md5

Il faut tout de même savoir que tous ses algorithmes de hashage sont vulnérables. Il existe en effet de nombreuses tables de hashage pré-calculées (ou tables de correspondances) grâce auxquelles on peut retrouver la valeur initiale d’un hash pour les chaines les plus courantes. De même, plus la chaine est chiffrée sur un grand nombre de caractères hexadécimaux, moins il existe de risque de collisions (c’est à dire plusieurs chaines différentes qui auront la même valeur de hashage).
SHA256('loicmorvan.fr') = 13b3f824aaabf403a7562b686070492b4e54ca4c42b291d558b78aae90d2d758
SHA512('loicmorvan.fr') = c94c4ed304f41c6667807beb90e5d629e9d5[...]e2d76f2d0d12b16bbbdc6e8f5660ee451f8
...

Bref, tout ça nous amène à la question :

Que choisir entre MD5, SHA-1 ou d’autres ?

Pour ma part, j’ai opté depuis longtemps pour l’algorithme MD5, sans vraiment y faire réfléchir jusqu’à la semaine dernière où avec un collègue, on s’est posé la question : est ce que ca joue sur les performances ? J’ai cherché des réponses sans en trouver réellement sur le net et du coup, j’ai fait mon propre bench… En voici les résultats :

Résultats

Temps total pour 1 000 000 d’appels (moyenne sur plusieurs exécutions) :

  • MD5 : 1.07 secondes
  • SHA-1 : 1.28 secondes

Pour information, il existe également en PHP la fonction hash faisant office de surcouche pour les fonctions md5 et sha1, mais permettant d’exécuter d’autres algorithmes de hashage tels que SHA-256, HAVAL160,4… Le passage par cette fonction pour le calcul des empreintes MD5 et SHA1 engendre une perte de temps de l’ordre de 30%.

Code du test

Voici le code qui m’a servi de test. Il a été exécuté sur un serveur dédié fonctionnant sous Linux / Gentoo, Apache2 et PHP 5.2.

$nb = 1000000;

echo ‘Nombre de tests à chaque fois : ‘.$nb;

$refString = ‘http://www.loicmorvan.fr’;

$string = $refString;
$time=microtime(1);
for ($i=0;$i<$nb;$i++) $string = hash(‘md5′, $string.$i);
echo microtime(1)-$time,’: hash/md5′;

$string = $refString;
$time=microtime(1);
for ($i=0;$i<$nb;$i++) $string = md5($string.$i);
echo microtime(1)-$time,’: md5′;

$string = $refString;
$time=microtime(1);
for ($i=0;$i<$nb;$i++) $string = hash(’sha1′, $string.$i);
echo microtime(1)-$time,’: hash/sha1′;

$string = $refString;
$time=microtime(1);
for ($i=0;$i<$nb;$i++) $string = sha1($string.$i);
echo microtime(1)-$time,’: sha1′;

Conclusion

La différence de temps entre ces deux fonctions est tout d’environ 20% ce qui est tout de même important, même si on fait rarement un million d’appels consécutifs et le risque de collisions étant déjà extrêmement faible en MD5 (1 chance sur 3*10^38), je ne peux que vous conseiller l’emploi de la fonction md5 par rapport à la fonction sha1.

En savoir plus :

  1. Libération mémoire cache Linux
  2. Microsoft TechDays 2009, j’y étais !
  3. .Net adapté pour les sites Internet personnels ?


8 réponses au sujet “PHP : Comparaison MD5 / SHA-1”

  • 1 SiM07   a écrit :

    Bon … la conclusion j’accroche pas vraiment surtout lorsqu’on ne précise pas qu’il faut absolument rajouter une chaine en plus dans le mot de passe. car faire un reverse d’un hash md5 d’un mot de passe basique est désormais très facile avec notre ami google. Avec sha1() c’est un peu plus difficile.

    Enfin maintenant, le choix de md5() ou sha1() n’est pas tant en soit le risque de collision mais qu’il n’est plus très sûr.

    Bref, si sha1 a été inventé ce n’est que pour une chose, remplacer md5 pour garantir une meilleur sécurité. On ne peut donc que conseiller son emploi.

  • 2 Nicolas Silberman   a écrit :

    La grande question est de savoir si le bénéfice de cette optimisation compense la perte en matière de sécurité. Personnellement je ne suis pas convaincu.

  • 3 Ludovic   a écrit :

    Bonjour,

    Personnellement choisir entre la sécurité ou la performance le choix est vite fait… Je fais généralement un sha1(md5(‘Mdp’)); de plus si c’est une zone « sensible » comme une administration j’y ajoute un grain de sel aléatoire.

    Entre la sécurité optimale ou gagner 0.2 sec … Normalement le choix est vite fait!

    Ludovic

  • 4 Loïc   a écrit :

    Merci pour vos commentaires.

    J’ai en effet omis de mentionner l’intérêt du fameux grain de sel comme le mentionne Ludovic qui permet d’encrypter de façon plus forte une chaine de caractères.

    En fait, à l’écriture de cet article, ma comparaison sur les performances pures, car je travaille pour plusieurs projets sur un système de cache qui délivrent des pages purement statiques (la partie dynamique étant générées en ajax). Mon besoin à ce moment était donc de stocker des résultats de requêtes html du type :
    /repertoire1/repertoire2/repertoire3/fichier.html
    dans un fichier et au final, ma conclusion est que, pour ce besoin, le md5 suffit amplement vu qu’il n’y a pas besoin de « sécurisation ».

    Mes fichiers de cache sont donc stockés de la manière suivante dans des fichiers du type : /repertoireCache/abcdef0123456789abcdef0123456789

    Et l’algorithme de mon cache est simple :
    Si le fichier de cache md5(url_demandée) existe
    alors on le retourne
    sinon on fait le traitement et on l’enregistre dans le fichier de cache md5(url_demandée)

    Merci pour vos commentaires.

  • 5 Ludovic   a écrit :

    Je comprends mieux, mais lorsque l’on fait un comparatif il est plus simple de le mettre dans son contexte pour que l’on puisse comprendre.

    Généralement md5 ou sha1 sont des algorithmes de hachage pour mot de passe… :-)

    Ludovic

  • 6 niahOo   a écrit :

    Merci pour ces infos. Pour des mots de passe, il faut empêcher de le trouver par force brute, en empêchant de dépasser un certain nombre de requêtes par minutes.

    Et si quelqu’un dispose du hash, ça veut dire qu’il est arrivé à lire dans ta base, la question de trouver le mot de passe pour lui ne se pose plus trop du coup :)

    Pour info, j’ai fais les tests sur un fichier de 6,63 Mo:
    Nombre de tests chaque fois : 1000000
    3.5786759853363: hash/md5
    2.8147709369659: md5
    4.0049850940704: hash/sha1
    3.1300539970398: sha1
    6.6954469680786: hash/sha256
    19.531332969666: hash/sha512

    J’ai fais aussi le test (sur windows vista) sur une chaine beaucoup plus longue que celle donnée dans l’exemple, mais à quelques microsecondes près ça ne changeait rien par rapport à l’exemple donné.

  • 7 Léo   a écrit :

    Composer les fonctions de hashage (e.g. faire sha1(md5(chaine))…) est complètement inutile car cela multiplie les risques de collisions (vous cumulez les vulnérabilités de md5 et de sha1…)

    Hé oui, supposons que les chaines A et B provoquent une collision, c’est a dire md5(A) = md5(B) = H

    sha1(md5(A)) = sha1(H) = H2
    sha1(md5(B)) = sha1(H) = H2
    Le cumul de fonctions n’a pas du tout évité la collision. Au contraire, vous prenez le risque de collisions supplémentaires dues à sha1.

    En crypto comme partout, les choses les plus simples sont souvent les plus efficaces, et les gros algos sacs de noeud vous explosent à la figure ^^

    L’utilisation d’un grain de sel est par contre obligatoire. Avec quelque chose d’aussi simple que sha1(chaine+salt), vous êtes plutôt tranquilles, même si le salt est connu de tous.

    PS : Mon commentaire précédent est à modérer, j’me’suis gouré ^^

  • 8 Syslog   a écrit :

    alors :
    SiM07, Nicolas Silberman, Ludovic x2

    MD5 et SHA ne servent pas seulement a crypter des mots de passe
    Ils sont aussi souvent utilisés pour vérifier que les data non pas été altérées

    par exemple quand vous téléchargez votre « Ubuntu » on vous fournit un condensat MD5 avec, ce qui vous permet de vérifier l’authenticité du quetru ;)

    et aussi il faut savoir que ni MD5 ni SHA sont 100% fiables

    je vous invite à lire Wikipedia a ce sujet ;)
    extrait
    « en février 2005, les universitaires chinois Xiaoyun Wang, Yiqun Lisa Yin et Hongbo Yu seraient parvenus à des collisions SHA-1 etc… »

    il ne faut pas utiliser les mots : toujours ou jamais dans ce domaine. parlons plutot de probabilité et d’improbabilité

    le monde n’est pas binaire, mais plein de nuances, les choses ne sont pas bonnes OU mauvaises,
    ne pensez pas comme ca les gars
    bref… là je m’égare la ;)

    un autre exemple de ce que je veux vous faire comprendre :
    meme si je « cryptais » mon pass avec CRC ou Adler combien de personnes seraient capables de le déchiffrer ?
    et parmi elles, combien en aurait la motivation ?

    SHA a été créé pour la NSA dans le but de protéger les codes de lancement d’arme nucléaire par exemple
    mais nous… a par Kevin 15 ans qui se prend pour un Hacker depuis qu’il télécharge sur Emule, qui va nous attaquer ? et on risque quoi ?

    et aussi , ne pas tout mélanger : car oui, peu importe l’épaisseur du blindage du coffre fort, si son proprio laisse la clef sou le paillasson ;)

    en resumé je trouve ton poste très pertinent Loïc Morvan et beaucoup moins ceux que j’ai cité au début
    (bien-sur ce n’est que mon humble avis les gars ! ;)

    et pour finir j’invite tous ceux qui m’ont compris et qui cherche la meme chose que Loic Morvan
    à se documenter sur « Tiger (hash) »
    « Tiger a été conçu et optimisé pour les systèmes 64 bits, il est surtout 3 fois plus rapide que le SHA-1 sur de tels processeurs. De plus, il est plus rapide que ses concurrents sur les machines 16 ou 32 bits. »

Ecrire un commentaire