Contrairement à ce que soulignent les réponses les plus positives ici, la non-injectivité (c'est -à- dire qu'il y a plusieurs chaînes de hachage à la même valeur) d'une fonction de hachage cryptographique causée par la différence entre une taille d'entrée importante (potentiellement infinie) et une taille de sortie fixe n'est pas le point important - en fait, nous préférons les fonctions de hachage où ces collisions se produisent aussi rarement que possible.
Considérez cette fonction (en notation PHP, comme question):
function simple_hash($input) {
return bin2hex(substr(str_pad($input, 16), 0, 16));
}
Cela ajoute des espaces, si la chaîne est trop courte, puis prend les 16 premiers octets de la chaîne, puis l'encode en hexadécimal. Il a la même taille de sortie qu'un hachage MD5 (32 caractères hexadécimaux, ou 16 octets si nous omettons la partie bin2hex).
print simple_hash("stackoverflow.com");
Cela produira:
737461636b6f766572666c6f772e636f6d
Cette fonction a également la même propriété de non-injectivité que celle mise en évidence par la réponse de Cody pour MD5: Nous pouvons passer des chaînes de toute taille (tant qu'elles tiennent dans notre ordinateur), et elle ne produira que 32 chiffres hexadécimaux. Bien sûr, cela ne peut pas être injectif.
Mais dans ce cas, il est trivial de trouver une chaîne qui correspond au même hachage (il suffit de l'appliquer hex2bin
sur votre hachage, et vous l'avez). Si votre chaîne d'origine avait la longueur 16 (comme notre exemple), vous obtiendrez même cette chaîne d'origine. Rien de ce genre ne devrait être possible pour MD5, même si vous savez que la longueur de l'entrée était assez courte (sauf en essayant toutes les entrées possibles jusqu'à ce que nous en trouvions une qui corresponde, par exemple une attaque par force brute).
Les hypothèses importantes pour une fonction de hachage cryptographique sont:
- il est difficile de trouver une chaîne produisant un hachage donné (résistance à la pré-image)
- il est difficile de trouver une chaîne différente produisant le même hachage qu'une chaîne donnée (deuxième résistance de pré-image)
- il est difficile de trouver une paire de chaînes avec le même hachage (résistance aux collisions)
Evidemment mon simple_hash
fonction ne remplit aucune de ces conditions. (En fait, si nous limitons l'espace d'entrée aux "chaînes de 16 octets", alors ma fonction devient injective, et est donc même prouvable résistante à la deuxième pré-image et aux collisions.)
Il existe maintenant des attaques par collision contre MD5 (par exemple, il est possible de produire une paire de chaînes, même avec un même préfixe donné, qui ont le même hachage, avec pas mal de travail, mais pas impossible beaucoup de travail), donc vous ne devriez pas utiliser MD5 pour tout ce qui est critique. Il n'y a pas encore d'attaque pré-image, mais les attaques s'amélioreront.
Pour répondre à la question réelle:
Qu'est-ce qui rend les chaînes résultantes impossibles à retracer dans ces fonctions?
Ce que MD5 (et d'autres fonctions de hachage s'appuient sur la construction Merkle-Damgard) fait effectivement, c'est appliquer un algorithme de chiffrement avec le message comme clé et une valeur fixe comme "texte brut", en utilisant le texte chiffré résultant comme hachage. (Avant cela, l'entrée est complétée et divisée en blocs, chacun de ces blocs est utilisé pour crypter la sortie du bloc précédent, XORed avec son entrée pour éviter les calculs inverses.)
Les algorithmes de cryptage modernes (y compris ceux utilisés dans les fonctions de hachage) sont conçus de manière à rendre difficile la récupération de la clé, même en utilisant à la fois du texte brut et du texte chiffré (ou même lorsque l'adversaire en choisit un). Ils le font généralement en effectuant de nombreuses opérations de brassage de bits de manière à ce que chaque bit de sortie soit déterminé par chaque bit clé (plusieurs fois) et également chaque bit d'entrée. De cette façon, vous ne pouvez retracer facilement ce qui se passe à l'intérieur que si vous connaissez la clé complète et l'entrée ou la sortie.
Pour les fonctions de hachage de type MD5 et une attaque de pré-image (avec une chaîne hachée à un seul bloc, pour faciliter les choses), vous n'avez que l'entrée et la sortie de votre fonction de cryptage, mais pas la clé (c'est ce que vous recherchez).