CRC32 Столкновение - PullRequest
       32

CRC32 Столкновение

12 голосов
/ 04 октября 2009

Я пытаюсь найти коллизию между двумя сообщениями, которая приведет к тому же хешу CRC. Учитывая, что я использую CRC32, можно ли как-нибудь сократить список возможных сообщений, которые я должен попробовать при проведении атаки методом перебора?

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

Ответы [ 7 ]

21 голосов
/ 05 октября 2009

Это полностью зависит от того, что вы подразумеваете под «сообщением». Если вы можете добавить четыре байта бреда к одному из сообщений. (Т.е. четыре байта, которые не имеют смысла в контексте сообщения.) Тогда оно становится тривиальным в прямом смысле этого слова.

Мышление в терминах битов, проходящих через конечный автомат CRC32.

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

В качестве примера представим, что у нас есть сдвиговый регистр, заполненный начальным состоянием 10101110, полиномом 10000011 и заполнением неизвестными битами, X.

Polynomial *     **  |feedback (End of SR.)
State      10101110     0
State      X1010111     1
State      XX101000     0
State      XXX10100     0
State      XXXX1010     0
State      XXXXX101     1
State      XXXXXX01     1
State      XXXXXXX1     1
State      XXXXXXXX     0

Обратная связь не относится к X, пока SR не будет заполнен! Таким образом, чтобы сгенерировать сообщение с заранее определенной контрольной суммой, вы берете новое сообщение, генерируете его CRC и обрабатываете следующие 32 бита обратной связи. Это вы можете сделать в 32 шагах функции CRC. Затем вам необходимо рассчитать влияние этой обратной связи на содержимое регистра сдвига.

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

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

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

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

Определение достаточного количества примеров в вашем сообщении - хитрый бит (если только вы не хотите обманывать пробелами!) CRC 32 является линейным, если данные имеют правильное смещение в сообщении. Таким образом, CRC ([messagea] [padding]) ^ CRC ([padding] [messageb]) = CRC ([messagea] [messageb]) Существуют некоторые предостережения с выравниванием слов, с которыми вам нужно справиться. Как общий совет, вы хотите расширить отрывки на «фиксированные» части сообщения. Как правило, вы хотите иметь альтернативы для n * 1,5 пассажей, где n - это размер CRC.

Теперь вы можете вычислить CRC, который имеет скелетное сообщение, впечатление, которое будет иметь каждый альтернативный отрывок, и затем составить таблицу, сравнивая влияние, которое окажет каждая альтернатива для каждого отрывка. Затем вам нужно выбрать альтернативы, которые изменят CRC скелета, чтобы соответствовать CRC, который вы хотите. Эту проблему на самом деле довольно забавно решить. Прежде всего найдите любые альтернативы, которые однозначно изменяют немного, если этот бит должен измениться для вашего CRC, выберите эту альтернативу и сложите ее влияние в CRC, а затем снова обойдите. Это должно уменьшить пространство для решения, которое вам нужно искать.

Это довольно сложная задача для кодирования, но это приведет к возникновению коллизий за очень короткий промежуток времени.

14 голосов
/ 05 октября 2009

Если не считать ошибки в моем исчислении, вероятность того, что не обнаружит одно столкновение после N испытаний, аппроксимирована в следующей таблице:

  N      Probability
-------  -----------
 50,000  74.7%
 77,000  50.1%
 78,000  49.2%
102,000  29.8%
110,000  24.5%
128,000  14.8%
150,000   7.3%
200,000   0.95%

Другими словами, вероятность необходимости вычисления более 200 000 значений CRC32 до нахождения дубликата составляет менее 1%, или вероятность нахождения дубликата до 102 000 попытки 70,2%
Кстати, это замечательно, потому что вероятность обнаружения одного столкновения, скажем, на самой 200 000-й попытке все еще составляет порядка 1/1000-й от 1% ((4M - 200,0000) / 4M), но, вероятно, обнаружение одного столкновения до 200 000-й попытки - это квази определенность (в любом случае, выше 99%). Это показывает заинтересованность в сохранении базы данных CRC, рассчитанной до сих пор .

Конечно, мы могли бы потратить некоторое время на изучение алгоритма CRC32 и лежащей в его основе математики, пытаясь найти сообщений с большей вероятностью вызвать коллизии CRC32 , но относительно небольшое количество действительно случайных попыток, необходимых для поиска По крайней мере, одно столкновение с квази определенностью делает такой подход криптоанализа едва ли стоящим усилий. Например, если предположить, что мы можем найти способ выбора сообщений, которые в 10 раз чаще сталкиваются друг с другом, нам все равно придется попробовать порядка 63 000 раз, прежде чем достичь вероятности 99% иметь хотя бы одно столкновение ( лучше, чем 200 000, но все еще требует примерно того же типа применения.)
Единственное, что мы можем рассмотреть в этой области, это избегать сообщений длиной менее 4 байт (я где-то читал, что CRC32 был биективен в этом пространстве сообщений) и избегать сообщений которые слишком похожи (то есть отличаются только на один или два символа), поскольку после первоначальной цели CRC32 обнаружение (и, возможно, автоматическое исправление) таких небольших различий в сообщениях.

Таким образом, похоже, что сложность задания заключается не столько в том, чтобы найти способы вычисления CRC32 на невероятной скорости (хотя мы не должны быть слишком медленными с этим), но скорее в для быстрого управления - база данных с возможностью поиска до 200 000 сообщений (или «ключ» сообщения, подробнее об этом ниже) и связанное с ними значение CRC32.

Несколько идей для реализации всего этого

  • Нужна простая библиотека ISAM или, что лучше, формальный интерфейс СУБД, такой как MySql или даже SqlLite.
  • Используя генератор псевдослучайных чисел (PRNG), для создания сообщений мы можем сохранить сообщение keys (т. Е. Все, что мы передаем PRNG для создания данного сообщения), вместо того, чтобы сохранять все сообщение . Это сделало бы вставки и поиск в базе данных более эффективными, рискуя ошибочно выбрать PRNG (или, точнее, случайные числа, основанные на генераторе сообщений), то есть такое, которое могло бы генерировать (поначалу) сообщения, которые как-то менее вероятны для CRC32- сталкиваются ...
  • Вероятно, лучше работать в пакетном режиме, т. Е. Производить, скажем, 1000 новых CRC, а затем проверять наличие коллизий и сохранять их, вместо того чтобы выполнять все эти операции для одного CRC за раз. Это особенно верно, если мы используем готовую СУБД
0 голосов
/ 17 мая 2018

spoof делает именно это. Не требует грубой силы.

0 голосов
/ 08 декабря 2011

Грубая сила, вам нужно около sqrt (6N) сообщений произвольной длины для хеша размера N, чтобы получить 95% вероятности столкновения. Например. CRC32, N = 2 ^ 32, вам нужно около 160 000 сообщений

0 голосов
/ 04 октября 2009

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

0 голосов
/ 04 октября 2009

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

- исправление: все не так просто. Тем не менее, это все еще тот способ, которым я бы воспользовался, пытаясь построить столкновение - вы должны следовать математике более подробно, чем я склонен сделать сегодня вечером ...

0 голосов
/ 04 октября 2009

Я предполагаю, что вы имеете в виду «сообщение» вместо «ключ».

Если вам разрешат выбрать оба «ключа», то грубая сила в любом случае будет довольно быстрой из-за парадокса дня рождения. Выберите случайные сообщения, вычислите их CRC, запомните их все и связанный CRC, и у каждого нового появляется все больше и больше шансов столкнуться с существующим по мере их накопления. Честно говоря, я ожидаю, что этот подход будет быстрее на современном компьютере, чем поиск известных подходов для коллизии CRC32.

...