Могут ли две разные строки генерировать один и тот же хэш-код MD5? - PullRequest
86 голосов
/ 18 ноября 2009

Для каждого из наших двоичных активов мы генерируем хеш MD5. Это используется для проверки, есть ли определенный бинарный актив в нашем приложении. Но возможно ли, что два разных бинарных ресурса генерируют один и тот же хеш MD5. Так возможно ли, что две разные строки генерируют один и тот же хеш MD5?

Ответы [ 11 ]

90 голосов
/ 18 ноября 2009

Для набора из даже миллиардов активов вероятность случайных столкновений ничтожно мала - ничего, о чем вам следует беспокоиться. Учитывая парадокс дня рождения , учитывая набор из 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). Недостатком является то, что он немного медленнее и имеет более длинный хэш-вывод.

37 голосов
/ 18 ноября 2009

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

В частности, обратите внимание, что коды MD5 имеют фиксированную длину, поэтому возможное количество кодов MD5 ограничено. Число строк (любой длины), однако, определенно не ограничено, поэтому логически следует, что должно быть коллизиями.

12 голосов
/ 18 ноября 2009

Да, это возможно. На самом деле это проблема дня рождения . Однако вероятность того, что две случайно выбранные строки имеют одинаковый хэш MD5, очень мала.

См. это и это вопросы для примеров.

10 голосов
/ 18 ноября 2009

Да, конечно: MD5-хэши имеют конечную длину, но существует бесконечное число возможных символьных строк, которые могут быть MD5-хэшированными.

6 голосов
/ 05 февраля 2016

Да, возможно, что две разные строки могут генерировать один и тот же хэш-код 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

Приведенный выше пример адаптирован из Дао Се и Дэнго Фэна: Создание коллизий MD5 с использованием всего одного блока сообщения , 2010.


Связанный:

4 голосов
/ 18 ноября 2009

Просто чтобы быть более информативным. С математической точки зрения хэш-функции не являются инъективными .
Это означает, что между начальным набором и полученным не существует отношения 1 к 1 (но в одну сторону).

Биекция в Википедии

РЕДАКТИРОВАТЬ: для полноты существуют инъективные хеш-функции: это называется Идеальное хеширование .

4 голосов
/ 18 ноября 2009

Да, это возможно. Это называется хеш-коллизия .

Сказав это, алгоритмы, такие как MD5, предназначены для минимизации вероятности столкновения.

Запись в Википедии MD5 объясняет некоторые уязвимости в MD5, о которых вам следует знать.

3 голосов
/ 18 ноября 2009

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

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

3 голосов
/ 18 ноября 2009

Да, это так! Столкновение будет возможным (хотя риск очень мал). Если нет, то у вас будет довольно эффективный метод сжатия!

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

2 голосов
/ 16 декабря 2016

Я понимаю, что это старо, но думал, что внесу свое решение. Есть 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...