Чи можуть два різні рядки генерувати однаковий хеш-код MD5?


93

Для кожного з наших двійкових активів ми генеруємо хеш MD5. Це використовується для перевірки того, чи певний двійковий актив вже є в нашому додатку. Але чи можливо, що два різні двійкові активи генерують однаковий хеш MD5. Тож чи можливо, що два різні рядки генерують однаковий хеш MD5?

Відповіді:


93

Для набору навіть мільярдів активів шанси випадкових зіткнень незначно малі - нічого, про що слід турбуватися. Враховуючи парадокс дня народження , з урахуванням набору з 2 ^ 64 (або 18 446 744 073 709 551 616) активів, ймовірність одного зіткнення MD5 у цьому наборі становить 50%. У такому масштабі ви, мабуть, перемогли Google за обсягом пам’яті.

Однак, оскільки хеш-функція MD5 порушена (вона вразлива до атаки зіткнення ), будь-який рішучий зловмисник може за лічені секунди заробити потужність центрального процесора за 2 секунди. Тож якщо ви хочете використовувати MD5, переконайтеся, що такий зловмисник не порушить безпеку вашої програми!

Також розгляньте наслідки, якщо зловмисник може створити зіткнення з наявним об’єктом у вашій базі даних. Хоча таких відомих атак ( атак перед зображеннями ) проти MD5 (станом на 2011 рік) немає, це могло б стати можливим шляхом розширення поточного дослідження атак зіткнень.

Якщо це виявляється проблемою, я пропоную розглянути хеш-функції серії SHA-2 (SHA-256, SHA-384 і SHA-512). Недоліком є ​​те, що він трохи повільніший і має довший хеш-результат.


4
На цей момент, на мою думку, "дні" - це надмірне завищення.
Нік Джонсон,

1
Правда, я оновив свій пост. Напад випадкових зіткнень 2004 року справді дуже швидкий. Атака зіткнення префіксів MD5 2007 року може зайняти дні - але, як правило, набагато корисніша для зловмисника
intgr

2
Див. Відповідь Рубенса для робочого прикладу, який породить зіткнення двох різних виконуваних файлів за лічені години. :)
Нік Джонсон

38

MD5 - це хеш-функція - так, так, два різні рядки можуть абсолютно генерувати зіткнулися коди MD5.

Зокрема, зверніть увагу, що коди MD5 мають фіксовану довжину, тому можлива кількість кодів MD5 обмежена. Однак кількість рядків (будь-якої довжини), безумовно, необмежена, тому логічно випливає, що мають бути колізії.


12

Так, це можливо. Це фактично проблема дня народження . Однак ймовірність двох випадково вибраних рядків, що мають однаковий хеш MD5, дуже низька.

Див. Це та це запитання для прикладів.


1
Яка ймовірність? Що зіткнення? Ні, це було б 1, тобто дуже високо. ;-)
Конрад Рудольф

Ну, правда. Напевно існують два рядки з однаковим хешем MD5.
гострий зуб

3
Я знав це як проблему голубиної нори.
Даніель А. Уайт

проблема дня народження стосується лише вірогідності зіткнення. для доказу повинен бути той, кого ви хочете, щоб принцип "піджей"
jk.

Я б проголосував за вашу відповідь двічі, якби міг. Наскільки "низька" ймовірність ми говоримо?
Alex Spencer

10

Так, звичайно: хеші MD5 мають кінцеву довжину, але існує нескінченна кількість можливих рядків символів, які можна хешувати MD5.


9

Так, цілком можливо, що два різні рядки можуть генерувати однаковий хеш-код MD5.

Ось простий тест із використанням дуже подібного двійкового повідомлення у шістнадцятковому рядку:

$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c6b384c4968b28812b676b49d40c09f8af4ed4cc  -
008ee33a9d58b51cfeb425b0959121c9

$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c728d8d93091e9c7b87b43d9e33829379231d7ca  -
008ee33a9d58b51cfeb425b0959121c9

Вони генерують різну суму SHA-1, але однакове хеш-значення MD5. По-друге, струни дуже схожі, тому важко знайти різницю між ними.

Різницю можна знайти за допомогою такої команди:

$ diff -u <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2 | fold -w2) <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2 | fold -w2)
--- /dev/fd/63  2016-02-05 12:55:04.000000000 +0000
+++ /dev/fd/62  2016-02-05 12:55:04.000000000 +0000
@@ -33,7 +33,7 @@
 af
 bf
 a2
-00
+02
 a8
 28
 4b
@@ -53,7 +53,7 @@
 6d
 a0
 d1
-55
+d5
 5d
 83
 60

Наведений вище приклад зіткнення взятий у Марка Стівенса: Зіткнення з одним блоком для MD5 , 2012; він пояснює свій метод із вихідним кодом ( альтернативне посилання на статтю ).


Ще один тест:

$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
756f3044edf52611a51a8fa7ec8f95e273f21f82  -
cee9a457e790cf20d4bdaa6d69f01e41

$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
6d5294e385f50c12745a4d901285ddbffd3842cb  -
cee9a457e790cf20d4bdaa6d69f01e41

Різна сума SHA-1, однаковий хеш MD5.

Різниця в одному байті:

$ diff -u <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2) <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2)
--- /dev/fd/63  2016-02-05 12:56:43.000000000 +0000
+++ /dev/fd/62  2016-02-05 12:56:43.000000000 +0000
@@ -19,7 +19,7 @@
 03
 65
 9e
-70
+74
 4f
 85
 34
@@ -41,7 +41,7 @@
 a3
 f4
 15
-5c
+dc
 bb
 86
 07

Наведений вище приклад адаптований з Tao Xie та Dengguo Feng: Побудуйте зіткнення MD5, використовуючи лише один блок повідомлень , 2010.


Пов’язані:


4

Так, це можливо. Це називається зіткненням Хеша .

Сказавши це, такі алгоритми, як MD5, розроблені для мінімізації ймовірності зіткнення.

Запис у Вікіпедії про MD5 пояснює деякі уразливості в MD5, про які вам слід знати.


4

Просто щоб бути більш інформативним. З математичної точки зору, функції хеш-функції не є ін'єктивними .
Це означає, що між стартовим набором і отриманим не існує співвідношення 1: 1 (а в один бік).

Бієкція у Вікіпедії

РЕДАКТУВАТИ: щоб бути повноцінними, існують ін'єктивні хеш-функції: це називається Ідеальне хешування .


1
Немає ідеальної функції хешування, коли розмір виводу менший за розмір введення.
Paŭlo Ebermann

3

Так! Зіткнення буде мати можливість (хоча, ризик дуже малий). Якщо ні, то у вас був би досить ефективний метод стиснення!

EDIT : Як говорить Конрад Рудольф: Потенційно необмежений набір вхідних даних, перетворений на кінцевий набір виводу (32 шістнадцяткові символи), призведе до нескінченної кількості колізій.


3

Як казали інші люди, так, між двома різними входами можуть бути зіткнення. Однак у вашому випадку використання я не бачу, що це проблема. Я дуже сумніваюся, що ви зіткнетеся зі зіткненнями - я використовував MD5 для відбитків пальців сотень тисяч файлів зображень із декількох форматів зображень (JPG, растрові зображення, PNG, необроблені файли) на попередній роботі, і у мене не було зіткнення .

Однак, якщо ви намагаєтеся взяти відбитки пальців якихось даних, можливо, ви можете скористатися двома алгоритмами хешування - шанси одного входу, що приводить до однакового виводу двох різних алгоритмів, майже неможливі.


1
Насправді, якщо зловмисник може викликати зіткнення з одним хеш-алгоритмом, він може використовувати це, щоб також отримати зіткнення для другого алгоритму. Нещодавно це було обговорено з мого питання на crypto.stackexchange .
Paŭlo Ebermann

2

Я усвідомлюю, що це старе, але думав, що внесу своє рішення. Існує 2 ^ 128 можливих комбінацій хешу. А отже, парадокс дня народження 2 ^ 64. Хоча наведене нижче рішення не усуне можливості зіткнення, воно, безсумнівно, зменшить ризик на дуже значну суму.

2^64 = 18,446,744,073,709,500,000 possible combinations

Те, що я зробив, це те, що я склав кілька хешів на основі вхідного рядка, щоб отримати набагато довший результуючий рядок, який ви вважаєте своїм хешем ...

Отже, мій псевдокод для цього:

Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string))

Тобто до практичної неймовірності зіткнення. Але якщо ви хочете бути супер параноїком і цього не може статися, і простір для зберігання даних не є проблемою (як і обчислювальні цикли) ...

Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string)) 
         & Hash(Reverse(SpellOutLengthWithWords(Length(string)))) 
         & Hash(Rotate13(string)) Hash(Hash(string)) & Hash(Reverse(Hash(string)))

Гаразд, не найчистіше рішення, але це тепер дає вам набагато більше гри з тим, як рідко ви зіткнетеся зі зіткненням. Точно я міг би припустити неможливість у всіх реалістичних сенсах цього терміну.

Заради мене, я думаю, що можливість зіткнення є досить рідкісною, що я вважатиму це не "надійним", але настільки навряд чи станеться, що відповідає потребі.

Тепер можливі комбінації значно зростають. Хоча ви могли б витратити довгий час на те, скільки комбінацій це може отримати для вас, я скажу, теоретично це приземлює вас НА ЗНАЧНО більше, ніж вказане вище число

2^64 (or 18,446,744,073,709,551,616) 

Можливо, ще на сто цифр або близько того. Теоретичний максимум, який це може дати вам, буде

Можлива кількість отриманих рядків:

528294531135665246352339784916516606518847326036121522127960709026673902556724859474417255887657187894674394993257128678882347559502685537250538978462939576908386683999005084168731517676426441053024232908211188404148028292751561738838396898767036476489538580897737998336


1

Я думаю, нам потрібно бути обережними з вибором алгоритму хешування відповідно до наших вимог, оскільки колізійні зіткнення не такі рідкісні, як я очікував. Нещодавно я знайшов дуже простий випадок хеш-зіткнення у своєму проекті. Я використовую обгортку Python xxhash для хешування. Посилання: https://github.com/ewencp/pyhashxx

s1 = 'mdsAnalysisResult105588'
s2 = 'mdsAlertCompleteResult360224'
pyhashxx.hashxx(s1) # Out: 2535747266
pyhashxx.hashxx(s2) # Out: 2535747266

Це спричинило дуже хитру проблему кешування в системі, тоді я нарешті виявив, що це хеш-зіткнення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.