Почему хэш-значения MD5 необратимы? - PullRequest
87 голосов
/ 01 декабря 2008

Одна концепция, которая меня всегда интересовала, - это использование криптографических хеш-функций и значений. Я понимаю, что эти функции могут генерировать хеш-значение, которое уникально и практически невозможно изменить, но вот что я всегда удивлялся:

Если на моем сервере, в PHP я выдаю:

md5("stackoverflow.com") = "d0cc85b26f2ceb8714b978e07def4f6e"

Когда вы запускаете эту же строку через функцию MD5, вы получаете тот же результат при установке PHP. Процесс используется для получения некоторого значения из некоторого начального значения.

Не означает ли это, что есть какой-то способ деконструировать происходящее и обратить вспять хэш-значение?

Что в этих функциях делает невозможным отслеживание полученных строк?

Ответы [ 16 ]

196 голосов
/ 01 декабря 2008

Входной материал может быть бесконечной длины, где выход всегда имеет длину 128 бит. Это означает, что бесконечное количество входных строк будет генерировать один и тот же вывод.

Если вы выберете случайное число и разделите его на 2, а только запишете остаток, вы получите либо 0, либо 1 - четное или нечетное соответственно. Можно ли взять это 0 или 1 и получить оригинальный номер?

49 голосов
/ 01 декабря 2008

Если бы хеш-функции, такие как MD5, были обратимыми, то это было бы переломным моментом в истории алгоритмов сжатия данных! Легко видеть, что если бы MD5 был обратимым, то произвольные порции данных произвольного размера могли бы быть представлены просто 128 битами без какой-либо потери информации. Таким образом, вы смогли бы восстановить исходное сообщение из 128-битного числа независимо от размера исходного сообщения.

27 голосов
/ 22 августа 2011

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

Рассмотрим эту функцию (в нотации PHP, как вопрос):

function simple_hash($input) {
     return bin2hex(substr(str_pad($input, 16), 0, 16));
}

Это добавляет некоторые пробелы, если строка слишком короткая, а затем занимает первые 16 байтов строки, а затем кодирует ее как шестнадцатеричное. Он имеет тот же размер вывода, что и хеш MD5 (32 шестнадцатеричных символа или 16 байтов, если мы опускаем часть bin2hex).

print simple_hash("stackoverflow.com");

Будет выведено:

737461636b6f766572666c6f772e636f6d

Эта функция также обладает тем же свойством неинъективности, что было выделено в ответе Коди для MD5: мы можем передавать строки любого размера (если они вписываются в наш компьютер), и она будет выводить только 32 шестнадцатеричных числа. Конечно, это не может быть инъективным.

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

Важные допущения для криптографической хеш-функции:

  • трудно найти какую-либо строку, производящую данный хэш (сопротивление прообразу)
  • трудно найти какую-либо другую строку, производящую тот же хеш, что и данная строка (сопротивление второму прообразу)
  • трудно найти любую пару строк с одинаковым хешем (сопротивлением столкновению)

Очевидно, что моя simple_hash функция не удовлетворяет ни одному из этих условий. (На самом деле, если мы ограничим пространство ввода «16-байтовыми строками», то моя функция станет инъективной, и, следовательно, даже доказуемо устойчивой ко второму изображению и столкновению.)

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

Чтобы ответить на актуальный вопрос:

Что в этих функциях делает результирующие строки невозможно отследить?

То, что MD5 (и другие хеш-функции строят на основе конструкции Меркля-Дамгарда), эффективно применяет алгоритм шифрования с сообщением в качестве ключа и некоторым фиксированным значением в качестве «простого текста», используя полученный зашифрованный текст в качестве хеша. (Перед этим вход дополняется и разделяется на блоки, каждый из этих блоков используется для шифрования выходных данных предыдущего блока, XORed с его входом для предотвращения обратных вычислений.)

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

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

17 голосов
/ 01 декабря 2008

Правильный ответ Коди Брошиуса. Строго говоря, вы не можете «инвертировать» хеш-функцию, потому что многие строки отображаются в один и тот же хеш. Заметьте, однако, что либо найти одну строку, которая сопоставлена ​​с данным хешем, либо найти две строки, которые сопоставлены с тем же хешем (т. Е. столкновение ), станет большим прорывом для криптоаналитика. Большая сложность обеих этих проблем является причиной того, что хорошие хеш-функции полезны в криптографии.

12 голосов
/ 01 декабря 2008

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

Например,

"hello" -> "1ab53"
"Hello" -> "993LB"
"ZR#!RELSIEKF" -> "1ab53"

(Очевидно, это не фактическое шифрование MD5)

Большинство хэшей (если не все) также не являются уникальными; скорее, они уникальны достаточно , поэтому столкновение крайне маловероятно, но все же возможно.

8 голосов
/ 13 декабря 2008

Хороший способ подумать о алгоритме хеширования - подумать об изменении размера изображения в Photoshop ... скажем, у вас есть изображение размером 5000x5000 пикселей, а затем вы измените его размер до 32x32. То, что у вас есть, по-прежнему представляет собой исходное изображение, но оно намного меньше и эффективно «отбрасывает» определенные части данных изображения, чтобы оно соответствовало меньшему размеру. Так что, если вы измените размер изображения 32x32 до 5000x5000, все, что вы получите, - это размытый беспорядок. Однако из-за того, что изображение размером 32x32 не так велико, теоретически можно предположить, что другое изображение можно уменьшить, чтобы получить точно такие же пиксели!

Это просто аналогия, но она помогает понять, что делает хеш.

4 голосов
/ 02 декабря 2008

Поскольку число возможных входных файлов превышает количество 128-битных выходных данных, невозможно однозначно назначить хэш MD5 для каждого возможного.

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

Эти критерии иногда используются:

  1. Сопротивление прообразу: для данной хеш-функции и данного хеша должно быть трудно найти вход, который имеет данный хеш для этой функции.
  2. Сопротивление второго прообраза: для данной хэш-функции и входных данных должно быть трудно найти второй, другой, вход с одинаковым хеш-значением.
  3. Сопротивление столкновению: для заданного имеет функцию, должно быть трудно найти два разных входа с одинаковым хешем.

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

Номер 3 подразумевает номер 2.

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

4 голосов
/ 01 декабря 2008

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

2 голосов
/ 13 марта 2012

Китайский ученый нашел способ, который называется «столкновения с выбранным префиксом», чтобы создать конфликт между двумя разными строками.

Вот пример: http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip
Исходный код: http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5_source.zip

2 голосов
/ 01 декабря 2008

Но именно здесь вступают в игру радужные столы. В основном это просто большое количество значений, хэшированных отдельно, а затем результат сохраняется на диск. Тогда бит реверса «просто» для поиска в очень большой таблице.

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

...