1.Проверял? Проверь и дай плз пример где это не сработало. ОК? 2. я чуть ошибся Код (Text): 127 126 125 124 123 122 121 119 118 117 116 115 114 113 111 110 109 108 107 106 103 102 101 100 99 97 95 94 93 92 89 87 86 85 83 82 81 79 76 74 73 71 69 68 67 62 61 59 58 57 53 51 47 46 43 41 38 37 34 31 29 23 19 17 3. А от куда тогда коллизии? 4. 2^(128-64)=2^64 чуть ошибся: 39614081257132168796771975168 было(до обнаружения ошибки) 18446744073709551616 стало
Код (Text): 011100110001100011101111110001010111011011011000110000100100101101000111010101000000110101011010110011111101010110001110010110[b]1[/b]0 хэш= 11100011011110110111100001101000011100111011101010000110110001110110010101001000110000001100101001100111011010000100111101010101 011100110001100011101111110001010111011011011000110000100100101101000111010101000000110101011010110011111101010110001110010110[b]0[/b]0 хеш= 11100011011110110111100001101000011100111011101010000110110001110110010101001000110000001100101001100111011010000100111101010101
2Black_sun ни одного совпадения. Проверь свой код Код (Text): #include <stdio.h> #include <windows.h> #include "md5.h" #define KBYTE 1024 #define MBYTE KBYTE*1024 #define DATA_SIZE 10*MBYTE BYTE Data[DATA_SIZE]; int main() { MD5_CTX ctx1, ctx2; BYTE Powers[8] = {1, 2, 4, 8, 16, 32, 64, 128}; ZeroMemory(Data, DATA_SIZE); for (int i=0; i<DATA_SIZE; i++) { for (int j=0; j<8; j++) { MD5Init(&ctx1); MD5Init(&ctx2); MD5Update(&ctx1, Data, DATA_SIZE); MD5Final(&ctx1); Data[i] |= Powers[j]; MD5Update(&ctx2, Data, DATA_SIZE); MD5Final(&ctx2); Data[i] &= ~(Powers[j]); if (!memcmp(ctx1.digest, ctx2.digest, 16)) { printf("%d - matched\n", i*8 + j); } } } return 0; }
Си это конечно же хорошо, но вот хотелось бы узнать что тут происходит. Разбирать чужую программу - дело неблагодарное и муторное. Приведи пример хеш функции(пароль желательно в бинарном виде запиши напамять ). А я тем времинем посмотрю что у меня не так. http://passcracking.ru/index.php - еще один подборщик паролей, хороший но воосновном до 8-ми символов.
Создается массив размером 10 мбайт. Далее в цикле по всем битам массива рассчитываются два хеша - один для исходного массива, второй - для этого же массива с измененным одним битом. Если оба хеша совпадают, на консоль выводим номер бита (не оказывающего влияние на md5). Как показывает программка, биты от 0 до 83886080 влияют на хеш. стандартная реализация из RFC
Обращаем МД5. Как известно алгоритм данной функции является односторонним, но сейчас мы попробуем его братить, зная тоько что его длинна будет у нас 128 бит. Рассмотрим пошагово: 1. Разбиваем данную(т.е. сам хеш) нам строку по блокам 32 бита и находим переменные ABCD до того как к ним был добавленн значение буфера(проводится быстро и довольно понятно, может я как нибудь нитак выразился, если вам не понятно). 2. Конечные значения ABCD мы получили теперь начинаем путь назад BCDA 9 21 64 b = c + ((b+ I(c,d,a) + X[9] + T[64]) <<< 21) Неизвестно у нас только b(Х=0 т.к. длинна 128 бит). Вичислить его достаточно просто (b -с) <<< 11=((b+ I(c,d,a) + X[9] + T[64]))<<< (11+21=32=0) (b -с) <<< 11=((b+ I(c,d,a) + X[9] + T[64])) b=((b -с) <<< 11)- I(c,d,a) - X[9] - T[64] b=((b -с) <<< 11)- I(c,d,a) - T[64] а дальше у нас появляется камень предкновения: CDAB 2 15 63 с = d+ ((c+ I(d,a,b) + X[2] + T[63]) <<< 15) Тут у нас уже 2 переменные, а как известно такие уравнение имеет ооочень много решений, это видно из уравнения: c=((c -d) <<< 17)- I(d,a,b) - T[63]- X[2] (1). Для наглядности ((c -d) <<< 17)- I(d,a,b) - T[63]=const c=const-X[2] const-c=X[2] (2) поэтому подним свои глаза в самый верх(в начало вычисления хеша: 1 раунд 3 операция): CDAB 2 17 3 (заметте 17+15=32, так к слову) с1 = d+ ((c+ I(d,a,b) + X[2] + T[3]) <<< 15) Тут сложновато, но можно сказть даже наоборот,поэтому приведем к тому же виду Получим: c1-const2=X[2] (3) (в конст2 вы наверное поняли что находится, и конечно нам его придется вычислять, но об этом чуть позже) Теперь зная что х2:х2=1 найдем отношения уравнений 2 и 3: (const-c):c1-const2=1 Частное решение которого является: c=const2 (4) c1=const Следовательно Х[2]=const -const2 с=d+ ((c+ I(d,a,b) + ((c -d) <<< 17)- I(d,a,b) - T[63]+T[63]-const2)<<<15
Вот продолжение: - из данного выражения следует что константа2 должна быть меньше константы1, но это необязательно так как отрицательных чисел в данном случае не существует. Так как консанту1 можно вычислить(напомню что она равна ((c -d) <<< 17)- I(d,a,b) - T[63]). То все дело встает за вычислением второй "константы": const2=(d<<<17)+c+i(d,a,b)+T[3] Х[2]=const -const2 Подставим в выражение значения констант: Х[2]=(c' -d') <<< 17)- I'(d,a,b) - T[63]-(d<<<17)-c-i(d,a,b)-T[3] как видно остается одна неизвестная, состоящая из 2х зависимых переменных, котрые мы вичисляем по циклу(какой цикл использовать это уже зависит от того какой входной поток мы хотим найти, к примеру по нахождении пароля используещго ассии(аски или ацки код) код понадобится ~2^40 операций+ советую ввести проверку полученного Х на коррректность, т.е. что бы значение каждого байта не превосходило 127 и было больше 32) Найдя х2 и зная что "с" предыдущее равно константе 2 проверим справедливость равенства с = d+ ((c+ I(d,a,b) + X[2] + T[63]) <<< 15), заранее вычислив х и с(хотя можно просто вычислить "с" обратив данную формулу и продолжать). теперь все гораздо проще [ABCD 4 6 61] Х по условию равно"10000000000000000000000000000000"- в двоичном коде Далее идут 4 операции [ABCD 8 6 57][DABC 15 10 58][CDAB 6 15 59][BCDA 13 21 60] - тут х=0 [BCDA 1 21 56] - помните мы уже вычислили х1 [CDAB 10 15 55] - х=0 DABC 3 10 54 - тут производим аналогичные вычисления(так как мы вычисляли х2, но тут уже все константы известны) [BCDA 5 21 52] [ABCD 12 6 53] - так же х=0 CDAB 14 15 51 - по умолчанию 128 бит был у нас входной поток DABC 7 10 50 - х=0 ABCD 0 6 49 - мы уже вычислили(точнее попытались предугодать) х0 уже в самом начале.