Эта статья входит в число добротных статей

MD5

Материал из Википедии — свободной энциклопедии
Текущая версия страницы покане проверялась опытными участниками и может значительно отличаться отверсии, проверенной 16 июля 2025 года; проверки требует1 правка.
Перейти к навигацииПерейти к поиску
MD5
Создан1991 г.
Опубликованапрель1992 г.
ПредшественникMD4
ПреемникSHA-2
СтандартыRFC 1321
Размер хеша128 бит
Число раундов4
Типхеш-функция

MD5 (англ. Message Digest 5) —128-битный алгоритмхеширования, разработанный профессоромРональдом Л. Ривестом изМассачусетского технологического института (Massachusetts Institute of Technology, MIT) в1991 году. Предназначен для создания «отпечатков» илидайджестов сообщения произвольной длины и последующей проверки их подлинности. Широко применялся для проверкицелостности информации и хранения хешей паролей.

Содержание

История

[править |править код]

MD5 — один из серии алгоритмов по построениюдайджеста сообщения, разработанный профессоромРональдом Л. Ривестом из Массачусетского технологического института. Был разработан в 1991 году как более надёжный вариант предыдущего алгоритмаMD4[1]. Описан вRFC 1321[2]. ПозжеГансом Доббертином были найдены недостатки алгоритма MD4.

В 1993 году Берт ден Бур (Bert den Boer) и Антон Босселарс (Antoon Bosselaers) показали, что в алгоритме возможны псевдоколлизии, когда разным инициализирующим векторам соответствуют одинаковые дайджесты для входного сообщения[3].

В 1996 году Ганс Доббертин (Hans Dobbertin) объявил о коллизии в алгоритме[4], и уже в то время было предложено использовать другие алгоритмы хеширования, такие какWhirlpool,SHA-1 илиRIPEMD-160.

Из-за небольшого размера хеша в 128 бит можно рассматриватьbirthday-атаки. В марте 2004 года был запущен проект MD5CRK с целью обнаружения уязвимостей алгоритма, при помощиbirthday-атаки. Проект MD5CRK закончился 17 августа 2004 года, когдаВан Сяоюнь (Wang Xiaoyun), Фэн Дэнго (Feng Dengguo),Лай Сюэцзя (Lai Xuejia) и Юй Хунбо (Yu Hongbo) обнаружили уязвимости в алгоритме[5].

1 марта 2005 годаАрьен Ленстра, Ван Сяоюнь и Бенне де Вегер продемонстрировали построение двух документовX.509 с различными открытыми ключами и одинаковым хешем MD5[6].

18 марта 2006 года исследовательВластимил Клима (Vlastimil Klima) опубликовал алгоритм, который может найти коллизии за одну минуту на обычном компьютере, метод получил название «туннелирование»[7].

В конце 2008 годаUS-CERT призвал разработчиков программного обеспечения, владельцев веб-сайтов и пользователей прекратить использовать MD5 в любых целях, так как исследования продемонстрировали ненадёжность этого алгоритма[8].

24 декабря 2010 года Тао Се (Tao Xie) и Фэн Дэнго (Feng Dengguo) впервые представили коллизию сообщений длиной в один блок (512 бит)[9].Ранее коллизии были найдены для сообщений длиной в два блока и более. Позднее Марк Стивенс (Marc Stevens) повторил успех, опубликовав блоки с одинаковым хешем MD5, а также алгоритм для получения таких коллизий[10].

В 2011 году был опубликован информационный документRFC 6151. Он признаёт алгоритм хеширования MD5[2] небезопасным для некоторых целей и рекомендует отказаться от его использования в пользу SHA-2.

Алгоритм MD5

[править |править код]
Схема работы алгоритма MD5. F — нелинейная функция.Mi обозначает 32-битный блок входного сообщения, аKi — 32-битную константу. <<<s обозначаетциклический сдвиг влево наs бит.{\displaystyle \boxplus } обозначает сложение по модулю 232. F зависит от раунда,Ki иs меняются каждую операцию.

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

Ниже приведены 5 шагов алгоритма[2]:

Шаг 1. Выравнивание потока

[править |править код]

Сначала к концу потока дописывают единичный бит.

Затем добавляют некоторое число нулевых бит такое, чтобы новая длина потокаL{\displaystyle L'} сталасравнима с 448 по модулю 512, (L=512×N+448{\displaystyle L'=512\times N+448}).Выравнивание происходит в любом случае, даже если длина исходного потока уже сравнима с 448.

Шаг 2. Добавление длины сообщения

[править |править код]

В конец сообщения дописывают 64-битное представление длины данных (количество бит в сообщении) до выравнивания.Сначала записывают младшие 4 байта, затем старшие. Если длина превосходит2641{\displaystyle 2^{64}-1}, то дописывают только младшие биты (эквивалентно взятию по модулю264{\displaystyle 2^{64}}). После этого длина потока станет кратной 512. Вычисления будут основываться на представлении этого потока данных в виде массива слов по 512 бит.

Шаг 3. Инициализация буфера

[править |править код]

Для вычислений инициализируются четыре переменные размером по 32 бита, начальные значения которых задаются шестнадцатеричными числами (порядок байтовlittle-endian):

А = 01 23 45 67; // 67452301hВ = 89 AB CD EF; // EFCDAB89hС = FE DC BA 98; // 98BADCFEhD = 76 54 32 10. // 10325476h

В этих переменных будут храниться результаты промежуточных вычислений. Начальное состояние ABCD называется инициализирующим вектором.

Шаг 4. Вычисление в цикле

[править |править код]

Определим функции и константы, которые понадобятся нам для вычислений.

  • Для каждого раунда потребуется своя функция. Введём функции от трёх параметров — слов, результатом также будет слово:
1-й этап:FunF(X,Y,Z)=(XY)(¬XZ){\displaystyle \operatorname {FunF} (X,Y,Z)=(X\wedge Y)\vee (\neg X\wedge Z)},
2-й этап:FunG(X,Y,Z)=(XZ)(¬ZY){\displaystyle \operatorname {FunG} (X,Y,Z)=(X\wedge Z)\vee (\neg Z\wedge Y)},
3-й этап:FunH(X,Y,Z)=XYZ{\displaystyle \operatorname {FunH} (X,Y,Z)=X\oplus Y\oplus Z},
4-й этап:FunI(X,Y,Z)=Y(¬ZX){\displaystyle \operatorname {FunI} (X,Y,Z)=Y\oplus (\neg {Z}\vee X)},
где,,,¬{\displaystyle \oplus ,\wedge ,\vee ,\neg } побитовые логические операцииXOR,AND,OR иNOT соответственно.
  • Определим таблицу константT[164]{\displaystyle T[1\ldots 64]} — 64-элементная таблица данных, построенная следующим образом:T[n]=int(232|sinn|){\displaystyle T[n]=\operatorname {int} (2^{32}\cdot |\sin n|)}[11].
  • Каждый 512-битный блок проходит 4 этапа вычислений по 16 раундов. Для этого блок представляется в виде массиваX из 16 слов по 32 бита. Все раунды однотипны и имеют вид: [abcd k s i], определяемый какa=b+((a+Fun(b,c,d)+X[k]+T[i])s){\displaystyle a=b+((a+\operatorname {Fun} (b,c,d)+X[k]+T[i])\lll s)}, гдеk — номер 32-битного слова из текущего 512-битного блока сообщения, иs{\displaystyle \ldots \lll s} — циклический сдвиг влево наs бит полученного 32-битного аргумента. Числоs задается отдельно для каждого раунда.

Заносим в блок данных элементn из массива 512-битных блоков. Сохраняются значения A, B, C и D, оставшиеся после операций над предыдущими блоками (или их начальные значения, если блок первый).

AA = A
BB = B
CC = C
DD = D

Этап 1

/* [abcd k s i] a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */[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]

Этап 2

/* [abcd k s i] a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */[ABCD  1 5 17][DABC  6 9 18][CDAB 11 14 19][BCDA  0 20 20][ABCD  5 5 21][DABC 10 9 22][CDAB 15 14 23][BCDA  4 20 24][ABCD  9 5 25][DABC 14 9 26][CDAB  3 14 27][BCDA  8 20 28][ABCD 13 5 29][DABC  2 9 30][CDAB  7 14 31][BCDA 12 20 32]

Этап 3

/* [abcd k s i] a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */[ABCD  5 4 33][DABC  8 11 34][CDAB 11 16 35][BCDA 14 23 36][ABCD  1 4 37][DABC  4 11 38][CDAB  7 16 39][BCDA 10 23 40][ABCD 13 4 41][DABC  0 11 42][CDAB  3 16 43][BCDA  6 23 44][ABCD  9 4 45][DABC 12 11 46][CDAB 15 16 47][BCDA  2 23 48]

Этап 4

/* [abcd k s i] a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */[ABCD  0 6 49][DABC  7 10 50][CDAB 14 15 51][BCDA  5 21 52][ABCD 12 6 53][DABC  3 10 54][CDAB 10 15 55][BCDA  1 21 56][ABCD  8 6 57][DABC 15 10 58][CDAB  6 15 59][BCDA 13 21 60][ABCD  4 6 61][DABC 11 10 62][CDAB  2 15 63][BCDA  9 21 64]

Суммируем с результатом предыдущего цикла:

A = AA + AB = BB + BC = CC + CD = DD + D

После окончания цикла необходимо проверить, есть ли ещё блоки для вычислений. Если да, то переходим к следующему элементу массива (n + 1) и повторяем цикл.

Шаг 5. Результат вычислений

[править |править код]

Результат вычислений находится в буфере ABCD, это и есть хеш. Если выводить побайтово, начиная с младшего байта A и заканчивая старшим байтом D, то мы получим MD5-хеш.1, 0, 15, 34, 17, 18…

Псевдокод

[править |править код]
// Все переменные — 32-битные беззнаковые целые. Все сложения выполняются по модулю 2^32.varints[64],K[64]varinti// s обозначает величины сдвигов для каждой операции:s[0..15] :={ 7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22 }s[16..31] :={ 5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20 }s[32..47] :={ 4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23 }s[48..63] :={ 6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21 }// Определяем таблицу констант следующим образомforifrom0to63doK[i] :=floor(2^32×abs(sin(i+1)))endfor// (Или просто используем заранее подсчитанные значения):K[0..3] :={ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee }K[4..7] :={ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 }K[8..11] :={ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be }K[12..15] :={ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 }K[16..19] :={ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa }K[20..23] :={ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 }K[24..27] :={ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed }K[28..31] :={ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a }K[32..35] :={ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c }K[36..39] :={ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 }K[40..43] :={ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 }K[44..47] :={ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 }K[48..51] :={ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 }K[52..55] :={ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 }K[56..59] :={ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 }K[60..63] :={ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }// Инициализация переменных:varinta0 :=0x67452301// Avarintb0 :=0xefcdab89// Bvarintc0 :=0x98badcfe// Cvarintd0 :=0x10325476// D// Подготовка: добавляем бит "1" в конец сообщения.append"1"bittomessage// Заметка: входные байты представлены строкой из бит,// причем первый бит — старший (big-endian).// Подготовка: дописываем нулевые биты, пока длина сообщения не станет сравнима с 448 по модулю 512append"0"bituntilmessagelengthinbits448(mod512)// Дописываем остаток от деления изначальной длины сообщения на 2^64appendoriginallengthinbitsmod2^64tomessage// Разбиваем подготовленное сообщение на 512-битные "куски":foreach512-bitchunkofpaddedmessagedo// и работаем с каждым по отдельностиbreakchunkintosixteen32-bitwordsM[j],0j15// разбиваем "кусок" на 16 блоков по 32 бита// Инициализируем переменные для текущего куска:varintA :=a0varintB :=b0varintC :=c0varintD :=d0// Основные операции:forifrom0to63dovarintF,gif0i15thenF :=(BandC)or((notB)andD)g :=ielseif16i31thenF :=(DandB)or((notD)andC)g :=(5×i+1)mod16elseif32i47thenF :=BxorCxorDg :=(3×i+5)mod16elseif48i63thenF :=Cxor(Bor(notD))g :=(7×i)mod16F :=F+A+K[i]+M[g]// M[g] — 32 битный блокA :=DD :=CC :=BB :=B+(F<<<s[i])// Выполняем битовый сдвигendfor// Прибавляем результат текущего "куска" к общему результатуa0 :=a0+Ab0 :=b0+Bc0 :=c0+Cd0 :=d0+Dendforvarchardigest[16] :=a0appendb0appendc0appendd0// (Результат в формате little-endian)

Результат вычислений на примере языка программирования Python

importhashlibimportmathk:intr:intdefleft_rotate(n,b):return((n<<b)|(n>>(32-b)))&0xffffffffdefmd5(message):a0=0x67452301b0=0xefcdab89c0=0x98badcfed0=0x10325476ml=len(message)*8message=bytearray(message)message.append(0x80)whilelen(message)%64!=56:message.append(0)message+=ml.to_bytes(8,byteorder='little')foriinrange(0,len(message),64):chunk=message[i:i+64]a=a0b=b0c=c0d=d0# Main loopforjinrange(64):if0<=j<=15:f=(b&c)|((~b)&d)g=jelif16<=j<=31:f=(d&b)|((~d)&c)g=(5*j+1)%16elif32<=j<=47:f=b^c^dg=(3*j+5)%16elif48<=j<=63:f=c^(b|(~d))g=(7*j)%16d_temp=dd=cc=bb=(b+left_rotate((a+f+k[j]+int.from_bytes(chunk[4*g:4*(g+1)],byteorder='little')),r[j]))&0xffffffffa=d_tempa0=(a0+a)&0xffffffffb0=(b0+b)&0xffffffffc0=(c0+c)&0xffffffffd0=(d0+d)&0xffffffffreturn'{:08x}{:08x}{:08x}{:08x}'.format(a0,b0,c0,d0)# Пример использования:importhashlibmessage="Hello, world!"result=hashlib.md5(message.encode()).hexdigest()print("MD5 хэш (hashlib):",result)defmd5(message):# ConstantsT=[int(abs(math.sin(i+1))*2**32)&0xFFFFFFFFforiinrange(64)]s=[[7,12,17,22]]*4+[[5,9,14,20]]*4+[[4,11,16,23]]*4+[[6,10,15,21]]*4# Initialize variablesA,B,C,D=0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476message=bytearray(message)length=(8*len(message))&0xFFFFFFFFFFFFFFFFmessage.append(0x80)whilelen(message)%64!=56:message.append(0x00)message.extend(length.to_bytes(8,byteorder='little'))# Process message in 16-word blocksforiinrange(0,len(message),64):X=[int.from_bytes(message[i:i+4],byteorder='little')foriinrange(i,i+64,4)]A_,B_,C_,D_=A,B,C,D# Main loopforjinrange(64):ifj<16:F=(B&C)|((~B)&D)F_index=jelifj<32:F=(D&B)|((~D)&C)F_index=(5*j+1)%16elifj<48:F=B^C^DF_index=(3*j+5)%16else:F=C^(B|(~D))F_index=(7*j)%16dTemp=DD=CC=BB=B+left_rotate((A+F+T[j]+X[F_index])&0xFFFFFFFF,s[j%4][j%4])A=dTemp# Update stateA=(A+A_)&0xFFFFFFFFB=(B+B_)&0xFFFFFFFFC=(C+C_)&0xFFFFFFFFD=(D+D_)&0xFFFFFFFF# Outputresult=bytearray(A.to_bytes(4,byteorder='little'))result.extend(B.to_bytes(4,byteorder='little'))result.extend(C.to_bytes(4,byteorder='little'))result.extend(D.to_bytes(4,byteorder='little'))returnresult.hex()result=md5(message.encode())print("MD5 хэш (самостоятельная реализация):",result)

Сравнение MD5 и MD4

[править |править код]

Алгоритм MD5 происходит от MD4. В новый алгоритм добавили ещё один раунд, теперь их стало 4 вместо 3 в MD4. Добавили новую константу для того, чтобы свести к минимуму влияние входного сообщения, в каждом раунде на каждом шаге и каждый раз константа разная, она суммируется с результатом F и блоком данных. Изменилась функцияG=XZ(Y¬Z){\displaystyle G=XZ\vee (Y\neg Z)} вместоXYXZYZ{\displaystyle XY\vee XZ\vee YZ}. Результат каждого шага складывается с результатом предыдущего шага, из-за этого происходит более быстрое изменение результата. Для этой же цели оптимизирована величина сдвига на каждом круге. Изменился порядок работы с входными словами в раундах 2 и 3[2].

Примеры MD5-хешей

[править |править код]

Хеш содержит 128 бит (16 байт) и обычно представляется как последовательность из 32шестнадцатеричных цифр[12].

Несколько примеров хеша:

 MD5("md5") = 1BC29B36F623BA82AAF6724FD3B16718

Даже небольшое изменение входного сообщения (в нашем случае на один бит: ASCII символ «5» с кодом 3516 = 0001101012 заменяется на символ «4» с кодом 3416 = 0001101002) приводит к полному изменению хеша. Такое свойство алгоритма называетсялавинным эффектом.

 MD5("md4") = C93D3BF7A7C4AFE94B64E30C2CE39F4F

Пример MD5-хеша для «нулевой» строки:

 MD5("") = D41D8CD98F00B204E9800998ECF8427E

Криптоанализ

[править |править код]

На данный момент существуют несколько видов «взлома» хешей MD5 — подбора сообщения с заданным хешем[13][14]:

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

Атаки переборного типа

[править |править код]

Дляполного перебора или перебора по словарю можно использовать программыPasswordsPro[15],MD5BFCPF[16],John the Ripper,Hashcat. Для перебора по словарю существуют готовые словари[17]. Основным недостатком такого типа атак является высокая вычислительная сложность.

RainbowCrack — ещё один метод нахожденияпрообраза хеша из заданного множества. Он основан на генерации цепочек хешей, чтобы по получившейся базе вести поиск заданного хеша. Хотя создание «радужных таблиц» занимает много времени и памяти, последующий взлом производится очень быстро. Основная идея данного метода — достижениекомпромисса между временем поиска по таблице и занимаемой памятью.

Коллизии MD5

[править |править код]

Коллизия хеш-функции — это получение одинакового значения функции для разных сообщений и идентичного начального буфера. В отличие от коллизий,псевдоколлизии определяются как равные значения хеша для разных значений начального буфера, причём сами сообщения могут совпадать или различаться. В MD5 вопрос коллизий не решается[14].

В 1996 годуГанс Доббертин нашёл псевдоколлизии в MD5, используя определённыеинициализирующие векторы, отличные от стандартных. Оказалось, что можно для известного сообщения построить второе, такое, что оно будет иметь такой же хеш, как и исходное. C точки зрения математики это означает: MD5(IV,L1) = MD5(IV,L2), где IV — начальное значение буфера, а L1 и L2 — различные сообщения. Например, если взять начальное значение буфера[4]:

A = 0x12AC2375В = 0x3B341042C = 0x5F62B97CD = 0x4BA763E

и задать входное сообщение

AA1DDABED97ABFF5BBF0E1C132774244
1006363E7218209DE01C136D9DA64D0E
98A1FB191FAE44B0236BB9926B7A779B
1326ED65D93E0972D458C8686B72746A

то, добавляя число29{\displaystyle 2^{9}} к определённому 32-разрядному слову в блочном буфере, можно получить второе сообщение с таким же хешем. Ханс Доббертин представил такую формулу:

L2i={L1i,i14;L1i+29,i=14.{\displaystyle L2_{i}={\begin{cases}L1_{i},&i\neq 14;\\L1_{i}+2^{9},&i=14.\end{cases}}}

Тогда MD5(IV, L1) = MD5(IV, L2) = BF90E670752AF92B9CE4E3E1B12CF8DE.

В 2004 году китайские исследователи Ван Сяоюнь (Wang Xiaoyun), Фэн Дэнго (Feng Dengguo),Лай Сюэцзя (Lai Xuejia) и Юй Хунбо (Yu Hongbo) объявили об обнаруженной ими уязвимости в алгоритме, позволяющей за небольшое время (1 час накластереIBM p690) находить коллизии[5][18].

В 2005 году Ван Сяоюнь и Юй Хунбо из университета Шаньдуна в Китае опубликовали алгоритм, который может найти две различные последовательности в 128 байт, которые дают одинаковый MD5-хеш. Одна из таких пар (различающиеся разряды выделены):

d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f89
55ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5b
d8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0
e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70

и

d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f89
55ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5b
d8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0
e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70

Каждый из этих блоков даёт MD5-хеш, равный 79054025255fb1a26e4bc422aef54eb4[19].

В 2006 году чешский исследователь Властимил Клима опубликовал алгоритм, позволяющий находитьколлизии на обычном компьютере с любым начальным вектором (A,B,C,D) при помощи метода, названного им «туннелирование»[7][20].

Алгоритм MD5 использует итерационныйметод Меркла — Дамгора, поэтому становится возможным построение коллизий с одинаковым, заранее выбранным префиксом. Аналогично, коллизии получаются при добавлении одинакового суффикса к двум различным префиксам, имеющим одинаковый хеш. В 2009 году было показано, что для любых двух заранее выбранных префиксов можно найти специальные суффиксы, с которыми сообщения будут иметь одинаковое значение хеша. Сложность такой атаки составляет всего 239 операций подсчёта хеша[21].

Метод Ван Сяоюня и Юй Хунбо

[править |править код]

МетодВан Сяоюня[англ.] иЮй Хунбо использует тот факт, что MD5 построен на итерационном методе Меркла — Дамгора. Поданный на вход файл сначала дополняется, так чтобы его длина была кратна 64 байтам, после этого он делится на блоки по 64 байта каждыйM0{\displaystyle M_{0}},M1{\displaystyle M_{1}},{\displaystyle \dots {}},Mn1{\displaystyle M_{n-1}}. Далее вычисляется последовательность 16-байтных состоянийs0{\displaystyle s_{0}},{\displaystyle \dots {}},sn{\displaystyle s_{n}} по правилуsi+1=f(si,Mi){\displaystyle s_{i+1}=f\left(s_{i},M_{i}\right)}, гдеf{\displaystyle f} — некоторая фиксированная функция. Начальное состояниеs0{\displaystyle s_{0}} называетсяинициализирующим вектором.

Метод позволяет для заданного инициализирующего вектора найти две парыM,M{\displaystyle M,M'} иN,N{\displaystyle N,N'}, такие чтоf(f(s,M),M)=f(f(s,N),N){\displaystyle f(f(s,M),M')=f(f(s,N),N')}. Этот метод работает для любого инициализирующего вектора, а не только для вектора используемого по стандарту.

Эта атака является разновидностьюдифференциальной атаки, которая, в отличие от других атак этого типа, использует целочисленное вычитание, а неXOR в качестве меры разности. При поиске коллизий используется метод модификации сообщений: сначала выбирается произвольное сообщениеM0{\displaystyle M_{0}}, далее оно модифицируется по некоторым правилам, сформулированным в статье, после чего вычисляется дифференциал хеш-функции, причёмM0=M0+dM0{\displaystyle M'_{0}=M_{0}+dM_{0}} с вероятностью237{\displaystyle {2}^{-37}}. КM0{\displaystyle M_{0}} иM0{\displaystyle M'_{0}} применяется функция сжатия для проверки условий коллизии; далее выбирается произвольноеM1{\displaystyle M_{1}}, модифицируется, вычисляется новый дифференциал, равный нулю с вероятностью230{\displaystyle {2}^{-30}}, а равенство нулю дифференциала хеш-функции как раз означает наличие коллизии. Оказалось, что найдя одну паруM0{\displaystyle M_{0}} иM0{\displaystyle M'_{0}}, можно менять лишь два последних слова вM0{\displaystyle M_{0}}, тогда для нахождения новой парыM1{\displaystyle M_{1}} иM1{\displaystyle M'_{1}} требуется всего около239{\displaystyle {2}^{39}} операций хеширования[19].

Применение этой атаки кMD4 позволяет найти коллизию меньше чем за секунду. Она также применима к другим хеш-функциям, таким какRIPEMD иHAVAL[5].

Примеры использования

[править |править код]

Ранее считалось, что MD5 позволяет получать относительно надёжный идентификатор для блока данных. На данный момент данная хеш-функция не рекомендуется к использованию, так как существуют способы нахожденияколлизий с приемлемой вычислительной сложностью[14][22].

Свойство уникальности хеша широко применяется в разных областях[23]. Приведенные примеры относятся и к другимкриптографическим хеш-функциям.

С помощью MD5 проверяли целостность и подлинность скачанных файлов — так, некоторые программы поставляются вместе со значениемконтрольной суммы. Например, пакеты для инсталляциисвободного ПО[24].

MD5 использовался для хеширования паролей. В системеUNIX каждый пользователь имеет свой пароль и его знает только пользователь. Для защиты паролей используется хеширование. Предполагалось, что получить настоящий пароль можно только полным перебором. При появленииUNIX единственным способом хеширования былDES (Data Encryption Standard), но им могли пользоваться только жителиСША, потому что исходные кодыDES нельзя было вывозить из страны. ВоFreeBSD решили эту проблему. ПользователиСША могли использовать библиотекуDES, а остальные пользователи имеют метод, разрешённый для экспорта. Поэтому вFreeBSD стали использовать MD5 по умолчанию[25]. НекоторыеLinux-системы также используют MD5 для хранения паролей[26].

Многие системы используют базы данных для аутентификации пользователей и существует несколько способов хранения паролей[27]:

  1. Пароли хранятся как есть. При взломе такой базы все пароли станут известны.
  2. Хранятся только хеши паролей. Найти пароли можно, используя заранее подготовленные таблицы хешей. Такие таблицы составляются из хешей простых или популярных паролей.
  3. К каждому паролю добавляется несколько случайных символов (их называют «соль») и результат хешируется. Полученный хеш вместе с «солью» сохраняются в открытом виде. Найти пароль с помощью таблиц таким методом не получится.

Существует несколько надстроек над MD5.

  • MD5 (HMAC) — Keyed-Hashing for Message Authentication (хеширование с ключом для аутентификации сообщения) — алгоритм позволяет хешировать входное сообщение L с некоторым ключом K, такое хеширование позволяет аутентифицировать подпись[28].
  • MD5 (Base64) — здесь полученный MD5-хеш кодируется алгоритмом Base64.
  • MD5 (Unix) — алгоритм вызывает тысячу раз стандартный MD5 для усложнения процесса. Также известен как MD5crypt[29].

Примечания

[править |править код]
  1. What are MD2, MD4, and MD5? (англ.). RSA Laboratories (2000). Дата обращения: 11 июля 2009. Архивировано изоригинала 23 августа 2011 года.
  2. 1234Rivest, 1992.
  3. Boer, Bosselaers, 1993.
  4. 12Hans Dobbertin. The Status of MD5 After a Recent Attack . Дата обращения: 22 октября 2015.
  5. 123Xiaoyun Wang, Dengguo Feng, Xuejia Lai, Hongbo Yu. Collisions for Hash Functions MD4, MD5, HAVAL-128 and RIPEMD (англ.) (17 августа 2004). Дата обращения: 19 ноября 2008. Архивировано изоригинала 23 августа 2011 года.
  6. Arjen Lenstra, Xiaoyun Wang and Benne de Weger. Colliding X.509 Certificates . eprint.iacr.org (1 марта 2005). Дата обращения: 4 декабря 2015. Архивировано 4 марта 2016 года.
  7. 12Vlastimil Kli'ma. Tunnels in Hash Functions: MD5 Collisions Within a Minute (англ.) (17 апреля 2006). Дата обращения: 19 ноября 2008. Архивировано изоригинала 23 августа 2011 года.
  8. CERT Vulnerability Note VU#836068 (англ.). kb.cert.org (30 декабря 2008). Дата обращения: 10 октября 2015. Архивировано 26 июля 2011 года.
  9. Tao Xie, Dengguo Feng. Construct MD5 Collisions Using Just A Single Block Of Message  (PDF) (16 декабря 2010). Дата обращения: 16 октября 2015. Архивировано 14 мая 2017 года.
  10. Marc Stevens – Research – Single-block collision attack on MD5 . Marc-stevens.nl (2012). Дата обращения: 16 октября 2015. Архивировано 15 мая 2017 года.
  11. Иными словами, в таблице представлены по 32 бита после десятичной запятой от значений функцииsin, где аргумент n в радианах.
  12. Detection Of Phishing Websites And Secure Transactions . Anna University (2012). Дата обращения: 20 октября 2015. Архивировано изоригинала 4 марта 2016 года.
  13. Ah Kioon, Wang, Deb Das, 2013.
  14. 123Updated Security Considerations for the MD5 Message-Digest and the HMAC-MD5 Algorithms . Internet Engineering Task Force (март 2011). Дата обращения: 23 октября 2015. Архивировано 15 июня 2017 года.
  15. PasswordsPro . InsidePro Software. — Программа для восстановления паролей к хешам различных типов. Дата обращения: 19 ноября 2008. Архивировано изоригинала 27 августа 2011 года.
  16. Проект MD5 на сайтеSourceForge.net
  17. CERIAS — Security Archive . Center for Education and Research in Information Assurance and Security (июнь 2000). Дата обращения: 19 ноября 2008. Архивировано 7 декабря 2008 года.
  18. Philip Hawkes, Michael Paddon, Gregory G. Rose. Musings on the Wang et al. MD5 Collision (англ.) (13 октября 2004). Дата обращения: 19 ноября 2008. Архивировано изоригинала 23 августа 2011 года.
  19. 12Wang, Yu, 2005.
  20. Vlastimil Klima. MD5 collisions (англ.). Дата обращения: 19 ноября 2008. Архивировано изоригинала 23 августа 2011 года.
  21. Stevens, Lenstra, Weger, 2012.
  22. Marc Stevens, Arjen Lenstra and Benne de Weger. Vulnerability of software integrity and code signing applications to chosen-prefix collisions for MD5  (30 ноября 2007). Дата обращения: 25 октября 2015. Архивировано 13 декабря 2007 года.
  23. Ilya Mironov. Hash functions: Theory, attacks, and applications . Microsoft Research (14 ноября 2005). Дата обращения: 13 ноября 2015. Архивировано 4 марта 2016 года.
  24. Turnbull J.Hardening Linux (англ.) — 1 —Apress, 2005. — P. 57—58.
  25. Bill Swingle. Руководство FreeBSD (DES, MD5 и шифрование)  (2006). Дата обращения: 20 ноября 2008. Архивировано изоригинала 17 сентября 2009 года.
  26. Vicki Stanfield, Roderick W. Smith. Linux System Administration (Craig Hunt Linux Library). — 2. — Sybex, 2002. — С. 479—483. — 656 с. —ISBN 978-0782141382.
  27. Hossein Bidgoli. The Internet Encyclopedia, Volume 3. — 1. — Wiley, 2003. — С. 3—4. — 908 с. —ISBN 978-0471222019.
  28. Krawczyk, Hugo, Canetti, Ran, Bellare, Mihir. HMAC: Keyed-Hashing for Message Authentication . tools.ietf.org. Дата обращения: 5 декабря 2015. Архивировано 15 апреля 2021 года.
  29. Steven Alexander. password protection for modern operating systems . USENIX 2004 (июнь 2004). Дата обращения: 5 декабря 2015. Архивировано 8 декабря 2015 года.

Литература

[править |править код]

Ссылки

[править |править код]
Перейти к шаблону «Хеш-алгоритмы»
Общего назначения
Криптографические
Функции формирования ключа
Контрольное число (сравнение)
Применение хешей
✰
Эта статья входит в числодобротных статей русскоязычного раздела Википедии.
Источник —https://ru.wikipedia.org/w/index.php?title=MD5&oldid=149725237
Категории:
Скрытые категории: