Алгоритм хеширования MD5.
1. Дополнение исходного сообщения, происходит следующим образом. Сначала к сообщению добавляется бит "1", затем добавляется столько битов "0", чтобы результирующая длина сообщения стала равной N*512+448. Дополнение происходит даже если сообщение уже соответствует этому условию. Далее, к полученному сообщению добавляется 64-битовое представление первоначальной длины сообщения (т.е. длина в битах, до того как добавили "1"). Если сообщение такое большое что его длина превышает 264, тогда берутся только 64 младших бита. В результате длина сообщения будет кратна 512, что и требовалось.
2. Инициализация четырех регистров A,B,C,D, каждый из которых содержит 32-битовое слово. Весь алгоритм сводится к операциям над этими регистрами. Изначально, в регистрах должны быть следующие значения: A = 0x67452301 B = 0xefcdab89 C = 0x98badcfe D = 0x10325476 Обратите внимание, что при реализации алгоритма везде нужно использовать 32-битовые беззнаковые числа. Например unsigned long int, если это C++.
3. Сообщение последовательно разбивается на блоки. Каждый блок содержит 16 32-битовых слов. Здесь нужно обратить внимание, в каком порядке данные помещаются в блок. Каждое слово в блоке в том же порядке, в котором даны исходные данные. Байты в каждом слове - от младшего к старшему (т.е. "наоборот"). Например, такая последовательность, взятая из исходных данных: 00000000 01100000 01110000 00000111 00011100 будет записана в слове блока так: 00011100 00000111 01110000 01100000 00000000
4. Определим четыре функции, выполняющие побитовые логические операции. Все три аргумента и возвращаемое значение - 32-битовые беззнаковые числа. F(X,Y,Z) = X and Y or not(X) and Z G(X,Y,Z) = X and Z or Y and not(Z) H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X or not(Z))
5. Определим операцию: R1 = R2 + ((R1 + Function(R2,R3,R4) + Block[k] + ConstTable[i]) <<< s) Где: R1,R2,R3,R4 - регистры (шаг 2) Function - одна из четырех функций (шаг 4) Block[k] - одно из слов текущего блока k=[0..15] ConstTable[i] - значение одной из 64 констант, которые вычисляются так: 4294967296*abs(sin(i)), где i в радианах, i=[1..64] <<< s - побитовый круговой сдвиг влево на s бит. При выполнении этой операции может произойти переполнение, полученное значение будет больше 32 бит. Лишние биты просто отбрасываются.
6. Значения каждого регистра сохраняются до конца этого шага. AA = A ... С текущим блоком выполняются четыре раунда, каждый из которых состоит из 16 операций (шаг 5). Первый раунд (операция [R1R2R3R4 k s i], Function=F): [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4] [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8] [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12] [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16] Далее, выполняются еще три аналогичных раунда.
Исчерпывающее описание MD5 на английском, описание всех раундов можно найти в RFC1321. Затем сохраненные в начале шага значения регистров добавляются к текущим: A = A + AA ... Действия, описанные в шаге 6 выполняются последовательно с каждым из блоков, на которые разбиты данные. После этого в регистрах A,B,C,D будет содержаться контрольная сумма. Байты в регистрах - от младшего к старшему.
Например: MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 Котрольная сумма для сообщения нулевой длины: MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
Теги: algorithms MD5
comments powered by Disqus