Jusqu'à quelle longueur de chaîne est-il possible d'utiliser MD5 comme hachage sans avoir à se soucier de la possibilité d'une collision?
Cela serait vraisemblablement calculé en générant un hachage MD5 pour chaque chaîne possible dans un jeu de caractères particulier, en augmentant la longueur, jusqu'à ce qu'un hachage apparaisse pour la deuxième fois (une collision). La longueur maximale possible d'une chaîne sans collision serait alors inférieure d'un caractère au plus long de la paire en collision.
Cela a-t-il déjà été testé pour MD5, SHA1, etc.?
Ironiquement, quelques semaines après avoir publié la réponse précédente, deux chercheurs chinois, Tao Xie et Dengguo Feng, ont publié une nouvelle collision monobloc pour MD5 . Je n'étais pas au courant de ce papier jusqu'à présent. Un seul bloc MD5 signifie que la taille d'entrée est de 64 octets ou 512 bits. Notez que les entrées sont généralement les mêmes, ne différant que sur 2 bits .
Leur méthodologie ne sera publiée qu'en janvier 2013, mais leur collision peut être vérifiée maintenant, en utilisant les chiffres du papier:
>>> from array import array
>>> from hashlib import md5
>>> input1 = array('I', [0x6165300e,0x87a79a55,0xf7c60bd0,0x34febd0b,0x6503cf04,
0x854f709e,0xfb0fc034,0x874c9c65,0x2f94cc40,0x15a12deb,0x5c15f4a3,0x490786bb,
0x6d658673,0xa4341f7d,0x8fd75920,0xefd18d5a])
>>> input2 = array('I', [x^y for x,y in Zip(input1,
[0, 0, 0, 0, 0, 1<<10, 0, 0, 0, 0, 1<<31, 0, 0, 0, 0, 0])])
>>> input1 == input2
False
>>> md5(input1).hexdigest()
'cee9a457e790cf20d4bdaa6d69f01e41'
>>> md5(input2).hexdigest()
'cee9a457e790cf20d4bdaa6d69f01e41'
Mise à jour: L'article a été publié en mars 2013: Tao Xie et Fanbao Liu et Dengguo Feng - Fast Collision Attack sur MD5
Cependant, si vous avez plus d'espace pour jouer avec, les collisions de quelques kilo-octets sont BEAUCOUP plus rapides à calculer - elles peuvent être calculées en quelques heures sur N'IMPORTE QUEL ordinateur ordinaire.
La collision la plus courte précédente a utilisé au moins deux blocs MD5 en entrée - soit 128 octets, 1024 bits. Un préfixe dans le premier bloc peut être choisi arbitrairement par l'attaquant, le reste serait calculé et apparaîtra comme du charabia.
Voici un exemple de deux entrées en collision différentes, vous pouvez l'essayer vous-même en Python:
>>> from binascii import unhexlify
>>> from hashlib import md5
>>> input1 = 'Oded Goldreich\nOded Goldreich\nOded Goldreich\nOded Go' + unhexlify(
... 'd8050d0019bb9318924caa96dce35cb835b349e144e98c50c22cf461244a4064bf1afaecc582'
... '0d428ad38d6bec89a5ad51e29063dd79b16cf67c12978647f5af123de3acf844085cd025b956')
>>> len(input1)
128
>>> md5(input1).hexdigest()
'd320b6433d8ebc1ac65711705721c2e1'
>>> input2 = 'Neal Koblitz\nNeal Koblitz\nNeal Koblitz\nNeal Koblitz\n' + unhexlify(
... '75b80e0035f3d2c909af1baddce35cb835b349e144e88c50c22cf461244a40e4bf1afaecc582'
... '0d428ad38d6bec89a5ad51e29063dd79b16cf6fc11978647f5af123de3acf84408dcd025b956')
>>> md5(input2).hexdigest()
'd320b6433d8ebc1ac65711705721c2e1'
La génération de ces deux entrées particulières a pris 2 jours sur un cluster PlayStation 3 à 215 nœuds, par Mark Stevens :)
Les mathématiques du paradoxe d'anniversaire font le point d'inflexion de probabilité de collision à peu près autour de sqrt (N), où N est le nombre de cases distinctes dans la fonction de hachage, donc pour un hachage de 128 bits, comme vous obtenez environ 64 bits, vous êtes modérément susceptible d'avoir 1 collision. Donc, je suppose que pour l'ensemble complet de chaînes de 8 octets, il est quelque peu susceptible d'avoir une collision, et pour les chaînes de 9 octets, il est extrêmement probable.
edit: cela suppose que l'algorithme de hachage MD5 provoque un mappage du bytestring d'entrée au hachage de sortie qui est proche de "aléatoire". (par rapport à celui qui répartit les chaînes plus uniformément parmi l'ensemble des hachages possibles, auquel cas il serait plus proche de 16 octets.)
Aussi pour une réponse numérique plus spécifique, si vous regardez ne des approximations pour calculer la probabilité de collision, vous obtenez
p (k) ≈ 1 - e-k (k-1)/(2 * 2128) où k = la taille de l'espace des entrées possibles = 2m où le bytestring d'entrée est long de m bits.
l'ensemble de 8 chaînes d'octets: p (264) ≈ 1 - e-0,5 ≈ 0,3935
l'ensemble de 9 chaînes d'octets: p (272) ≈ 1 - e-2144/ (2 * 2128) = 1 - e-215 = 1 - e-32768 ≈ 1
Notez également que ceux-ci supposent l'ensemble complet de chaînes de m/8 octets. Si vous n'utilisez que des caractères alphanumériques, vous auriez besoin de plus d'octets pour obtenir une collision probable.
Je doute qu'il y ait une longueur utile où vous n'allez pas avoir de collisions possibles. Ces algorithmes ne sont pas vraiment utilisés à cette fin. Il est destiné à essayer d'être unique pour de légères modifications dans les données (comme les fichiers corrompus) plutôt que unique sur tous les ensembles de données possibles.