учебники, программирование, основы, введение в,

 

Хэш-функции и аутентификация сообщений.

Хэш-функции
Требования к хэш-функциям
Хэш-функцией называется односторонняя функция, предназначенная для получения дайджеста или "отпечатков пальцев" файла, сообщения или некоторого блока данных.
Хэш-код создается функцией Н:
h = H (M)
Где М является сообщением произвольной длины и h является хэш-кодом фиксированной длины.
Рассмотрим требования, которым должна соответствовать хэш-функция для того, чтобы она могла использоваться в качестве аутентификатора сообщения. Рассмотрим очень простой пример хэш-функции. Затем проанализируем несколько подходов к построению хэш-функции.
Хэш-функция Н, которая используется для аутентификации сообщений, должна обладать следующими свойствами:

  1. Хэш-функция Н должна применяться к блоку данных любой длины.
  2. Хэш-функция Н создает выход фиксированной длины.
  3. Н (М) относительно легко (за полиномиальное время) вычисляется для любого значения М.
  4. Для любого данного значения хэш-кода h вычислительно невозможно найти M такое, что Н (M) = h.
  5. Для любого данного х вычислительно невозможно найти y x, что H (y) = H (x).
  6. Вычислительно невозможно найти произвольную пару (х, y) такую, что H (y) = H (x).

Первые три свойства требуют, чтобы хэш-функция создавала хэш-код для любого сообщения.
Четвертое свойство определяет требование односторонности хэш-функции: легко создать хэш-код по данному сообщению, но невозможно восстановить сообщение по данному хэш-коду. Это свойство важно, если аутентификация с использованием хэш-функции включает секретное значение. Само секретное значение может не посылаться, тем не менее, если хэш-функция не является односторонней, противник может легко раскрыть секретное значение следующим образом. При перехвате передачи атакующий получает сообщение М и хэш-код С = Н (SAB || M). Если атакующий может инвертировать хэш-функцию, то, следовательно, он может получить SAB || M = H-1 (C). Так как атакующий теперь знает и М и SAB || M, получить SAB совсем просто.
Пятое свойство гарантирует, что невозможно найти другое сообщение, чье значение хэш-функции совпадало бы со значением хэш-функции данного сообщения. Это предотвращает подделку аутентификатора при использовании зашифрованного хэш-кода. В данном случае противник может читать сообщение и, следовательно, создать его хэш-код. Но так как противник не владеет секретным ключом, он не имеет возможности изменить сообщение так, чтобы получатель этого не обнаружил . Если данное свойство не выполняется, атакующий имеет возможность выполнить следующую последовательность действий: перехватить сообщение и его зашифрованный хэш-код, вычислить хэш-код сообщения, создать альтернативное сообщение с тем же самым хэш-кодом, заменить исходное сообщение на поддельное. Поскольку хэш-коды этих сообщений совпадают, получатель не обнаружит подмены.
Хэш-функция, которая удовлетворяет первым пяти свойствам, называется простой или слабой хэш-функцией. Если кроме того выполняется шестое свойство, то такая функция называется сильной хэш-функцией. Шестое свойство защищает против класса атак, известных как атака "день рождения".

Простые хэш-функции

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

Сi = bi1  bi2  . . .  bik

Где


Сi - i-ый бит хэш-кода, 1 i n.

k - число n-битных блоков входа.

bij - i-ый бит в j-ом блоке.

- операция XOR.

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

  • Установить n-битный хэш-код в ноль.
  • Для каждого n-битного блока данных выполнить следующие операции:
    • сдвинуть циклически текущий хэш-код влево на один бит;
    • выполнить операцию XOR для очередного блока и хэш-кода.

Это даст эффект "случайности" входа и уничтожит любую регулярность, которая присутствует во входных значениях.
Хотя второй вариант считается более предпочтительным для обеспечения целостности данных и предохранения от случайных сбоев, он не может использоваться для обнаружения преднамеренных модификаций передаваемых сообщений. Зная сообщение, атакующий легко может создать новое сообщение, которое имеет тот же самый хэш-код. Для этого следует подготовить альтернативное сообщение и затем присоединить n-битный блок, который является хэш-кодом нового сообщения, и блок, который является хэш-кодом старого сообщения.
Хотя простого XOR или ротационного XOR (RXOR) недостаточно, если целостность обеспечивается только зашифрованным хэш-кодом, а само сообщение не шифруется, подобная простая функция может использоваться, когда все сообщение и присоединенный к нему хэш-код шифруются. Но и в этом случае следует помнить о том, что подобная хэш-функция не может проследить за тем, чтобы при передаче последовательность блоков не изменилась. Это происходит в силу того, что данная хэш-функция определяется следующим образом: для сообщения, состоящего из последовательности 64-битных блоков Х1, Х2,..., ХN, определяется хэш-код С как поблочный XOR всех блоков, который присоединяется в качестве последнего блока:

С = ХN+1 = X1  X2  . . .  XN

Затем все сообщение шифруется, включая хэш-код, в режиме СВС для создания зашифрованных блоков Y1, Y2, ..., YN+1. По определению СВС имеем:

Х1 = IV  DK [Y1]
Хi = Yi-1  DK [Yi]
ХN+1 = YN  DK [YN+1]

Но XN+1 является хэш-кодом:

ХN+1 = X1  X2  . . .  XN = 
(IV  DK [Y1])  (Y1  DK [Y2])  . . .  
(YN-1  DK [YN])

Так как сомножители в предыдущем равенстве могут вычисляться в любом порядке, следовательно, хэш-код не будет изменен, если зашифрованные блоки будут переставлены.
Первоначальный стандарт, предложенный NIST, использовал простой XOR, который применялся к 64-битным блокам сообщения, затем все сообщение шифровалось, используя режим СВС.

"Парадокс дня рождения"

Прежде чем рассматривать более сложные хэш-функции, необходимо проанализировать одну конкретную атаку на простые хэш-функции.
Так называемый "парадокс дня рождения" состоит в следующем. Предположим, количество выходных значений хэш-функции Н равна n. Каким должно быть число k, чтобы для конкретного значения X и значений Y1, …, Yk вероятность того, что хотя бы для одного Yi выполнялось равенство

H (X) = H (Y)

была бы больше 0,5.
Для одного Y вероятность того, что H (X) = H (Y), равна 1/n.
Соответственно, вероятность того, что H(X) H(Y), равна 1 - 1/n.
Если создать k значений, то вероятность того, что ни для одного из них не будет совпадений, равна произведению вероятностей, соответствующих одному значению, т.е. (1 - 1/n)k.
Следовательно, вероятность, по крайней мере, одного совпадения равна

1 - (1 - 1/n)k

По формуле бинома Ньютона

(1 - a)k = 
1 - ka + (k(k-1)/2!)a2 - ... ≈ 1 - ka
1 - (1 - k/n) = k/n = 0,5
k = n/2

Таким образом, мы выяснили, что для m-битового хэш-кода достаточно выбрать 2m-1 сообщений, чтобы вероятность совпадения хэш-кодов была больше 0,5.
Теперь рассмотрим следующую задачу: обозначим P (n, k) вероятность того, что в множестве из k элементов, каждый из которых может принимать n значений, есть хотя бы два с одинаковыми значениями. Чему должно быть равно k, чтобы P (n, k) была бы больше 0,5?
Число различных способов выбора элементов таким образом, чтобы при этом не было дублей, равно

n(n-1) … (n-k+1)n!/(n-k)!

Всего возможных способов выбора элементов равно

nk

Вероятность того, что дублей нет, равна

n!/(n-k)!nk 

Вероятность того, что есть дубли, соответственно равна

1 - n!/(n-k)!nk
P (n, k) = 1 - n! / ((n-k)! × nk) = 
1 - (n × (n-1) × … × (n-k-1)) / nk = 
1 - [ (n-1)/n × (n-2)/n × … × (n-k+1)/n] = 
1 - [(1- 1/n) × (1 - 2/n) × … × (1 - (k-1)/n)]

Известно, что

1 - x  e-x 
P (n, k) > 1 - [e-1/n × e-2/n × … × e-k/n]
P (n, k) > 1 - e-k(k-1)/n
1/2 = 1 - e-k(k-1)/n
2 = ek(k-1)/n
ln 2 = k (k-1) / 2n
k (k-1) ≈ k2
k = (2n × ln 2)1/2 = 1,17 n1/2 ≈ n1/2

Если хэш-код имеет длину m бит, т.е. принимает 2m значений, то

k = √2m = 2m/2

Подобный результат называется "парадоксом дня рождения", потому что в соответствии с приведенными выше рассуждениями для того, чтобы вероятность совпадения дней рождения у двух человек была больше 0,5, в группе должно быть всего 23 человека. Этот результат кажется удивительным, возможно, потому, что для каждого отдельного человека в группе вероятность того, что с его днем рождения совпадет день рождения кого-то другого в группе, достаточно мала.
Вернемся к рассмотрению свойств хэш-функций. Предположим, что используется 64-битный хэш-код. Можно считать, что это вполне достаточная и, следовательно, безопасная длина для хэш-кода. Например, если зашифрованный хэш-код С передается с соответствующим незашифрованным сообщением М, то противнику необходимо будет найти М' такое, что

Н (М') = Н (М)

для того, чтобы подменить сообщение и обмануть получателя. В среднем противник должен перебрать 263 сообщений для того, чтобы найти такое, у которого хэш-код равен перехваченному сообщению.
Тем не менее, возможны различного рода атаки, основанные на "парадоксе дня рождения". Возможна следующая стратегия:

  1. Противник создает 2m/2 вариантов сообщения, каждое из которых имеет некоторый определенный смысл. Противник подготавливает такое же количество сообщений, каждое из которых является поддельным и предназначено для замены настоящего сообщения.
  2. Два набора сообщений сравниваются в поисках пары сообщений, имеющих одинаковый хэш-код. Вероятность успеха в соответствии с "парадоксом дня рождения" больше, чем 0,5. Если соответствующая пара не найдена, то создаются дополнительные исходные и поддельные сообщения до тех пор, пока не будет найдена пара.
  3. Атакующий предлагает отправителю исходный вариант сообщения для подписи. Эта подпись может быть затем присоединена к поддельному варианту для передачи получателю. Так как оба варианта имеют один и тот же хэш-код, будет создана одинаковая подпись. Противник будет уверен в успехе, даже не зная ключа шифрования.

Таким образом, если используется 64-битный хэш-код, то необходимая сложность вычислений составляет порядка 232.
В заключение отметим, что длина хэш-кода должна быть достаточно большой. Длина, равная 64 битам, в настоящее время не считается безопасной. Предпочтительнее, чтобы длина составляла порядка 100 битов.

Использование цепочки зашифрованных блоков

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

Н0 = начальное значение
Нi = EMi [Hi-1]
G = HN

Это аналогично использованию шифрования в режиме СВС, но в данном случае секретного ключа нет. Как и в случае любой простой хэш-функции, этот алгоритм подвержен "атаке дня рождения", и если шифрующим алгоритмом является DES и создается только 64-битный хэш-код, то система считается достаточно уязвимой.
Могут осуществляться другие атаки типа "дня рождения", которые возможны даже в том случае, если противник имеет доступ только к одному сообщению и соответствующему ему зашифрованному хэш-коду и не может получить несколько пар сообщений и зашифрованных хэш-кодов. Возможен следующий сценарий: предположим, что противник перехватил сообщение с аутентификатором в виде зашифрованного хэш-кода, и известно, что незашифрованный хэш-код имеет длину m битов. Далее противник должен выполнить следующие действия:

  • Используя описанный выше алгоритм, вычислить незашифрованный хэш-код G.
  • Создать поддельное сообщение в виде Q1, Q2, . . . , QN-2.
  • Вычислить Нi = EQi[Hi-1] для 1 i N-2.
  • Создать 2m/2 случайных блока Х и для каждого такого блока Х вычислить ЕХ[HN-2]. Создать дополнительно 2m/2 cлучайных блока Y и для каждого блока Y вычислить DY[G], где D - дешифрующая функция, соответствующая Е. Основываясь на "парадоксе дня рождения" можно сказать, что с высокой степенью вероятности эта последовательность будет содержать блоки Х и Y такие, что ЕХ[HN-2] = DY[Y].
  • Создать сообщение Q1, Q2, . . . ,QN-2, X, Y. Это сообщение имеет хэш-код G и, следовательно, может быть использовано вместе с зашифрованным аутентификатором.

Эта форма атаки известна как атака "встреча посередине". В различных исследованиях предлагаются более тонкие методы для усиления подхода, основанного на цепочке блоков. Например, Девис и Прайс описали следующий вариант:

Hi = EMi [Hi-1]  Hi-1

Возможен другой вариант:

Hi = EHi-1 [Mi]  Mi

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

Хэш-функция MD5

Рассмотрим алгоритм получения дайджеста сообщения MD5 (RFC 1321), разработанный Роном Ривестом из MIT.

Логика выполнения MD5

Алгоритм получает на входе сообщение произвольной длины и создает в качестве выхода дайджест сообщения длиной 128 бит. Алгоритм состоит из следующих шагов:
Шаг 1: добавление недостающих битов
Сообщение дополняется таким образом, чтобы его длина стала равна 448 по модулю 512 (длина 448 mod 512). Это означает, что длина добавленного сообщения на 64 бита меньше, чем число, кратное 512. Добавление производится всегда, даже если сообщение имеет нужную длину. Например, если длина сообщения 448 битов, оно дополняется 512 битами до 960 битов. Таким образом, число добавляемых битов находится в диапазоне от 1 до 512.
Добавление состоит из единицы, за которой следует необходимое количество нулей.
Шаг 2: добавление длины
64-битное представление длины исходного (до добавления) сообщения в битах присоединяется к результату первого шага. Если первоначальная длина больше, чем 264, то используются только последние 64 бита. Таким образом, поле содержит длину исходного сообщения по модулю 264.
В результате первых двух шагов создается сообщение, длина которого кратна 512 битам. Это расширенное сообщение представляется как последовательность 512-битных блоков Y0, Y1, . . ., YL-1, при этом общая длина расширенного сообщения равна L * 512 битам. Таким образом, длина полученного расширенного сообщения кратна шестнадцати 32-битным словам.
Шаг 3: инициализация MD-буфера
Используется 128-битный буфер для хранения промежуточных и окончательных результатов хэш-функции. Буфер может быть представлен как четыре 32-битных регистра (A, B, C, D). Эти регистры инициализируются следующими шестнадцатеричными числами:

А = 01234567
В = 89ABCDEF
C = FEDCBA98
D = 76543210

Шаг 4: обработка последовательности 512-битных (16-словных) блоков
Основой алгоритма является модуль, состоящий из четырех циклических обработок, обозначенный как HMD5. Четыре цикла имеют похожую структуру, но каждый цикл использует свою элементарную логическую функцию, обозначаемую fF, fG, fH и fI соответственно.
Каждый цикл принимает в качестве входа текущий 512-битный блок Yq, обрабатывающийся в данный момент, и 128-битное значение буфера ABCD, которое является промежуточным значением дайджеста, и изменяет содержимое этого буфера. Каждый цикл также использует четвертую часть 64-элементной таблицы T[1 ... 64], построенной на основе функции sin. i-ый элемент T, обозначаемый T[i], имеет значение, равное целой части от 232 * abs (sin (i)), i задано в радианах. Так как abs (sin (i)) является числом между 0 и 1, каждый элемент Т является целым, которое может быть представлено 32 битами. Таблица обеспечивает "случайный" набор 32-битных значений, которые должны ликвидировать любую регулярность во входных данных.
Для получения MDq+1 выход четырех циклов складывается по модулю 232 с MDq. Сложение выполняется независимо для каждого из четырех слов в буфере.
Шаг 5: выход
После обработки всех L 512-битных блоков выходом L-ой стадии является 128-битный дайджест сообщения.
Рассмотрим более детально логику каждого из четырех циклов выполнения одного 512-битного блока. Каждый цикл состоит из 16 шагов, оперирующих с буфером ABCD. Каждый шаг можно представить в виде:

A ← B + CLSs (A + f (B, C, D) + X [k] + T [i])

где


A, B, C, D - четыре слова буфера; после выполнения каждого отдельного шага происходит циклический сдвиг влево на одно слово.

f - одна из элементарных функций fF, fG, fH, fI.

CLSs - циклический сдвиг влево на s битов 32-битного аргумента.

X [k] - M [q * 16 + k] - k-ое 32-битное слово в q-ом 512 блоке сообщения.

T [i] - i-ое 32-битное слово в матрице Т.

+ - сложение по модулю 232.

На каждом из четырех циклов алгоритма используется одна из четырех элементарных логических функций. Каждая элементарная функция получает три 32-битных слова на входе и на выходе создает одно 32-битное слово. Каждая функция является множеством побитовых логических операций, т.е. n-ый бит выхода является функцией от n-ого бита трех входов. Элементарные функции следующие:

fF = (B & C)  (not B & D)
fG = (B & D) V (C & not D)
fH = B  C  D
fI = C  (B & not D)

Массив из 32-битных слов X [0..15] содержит значение текущего 512-битного входного блока, который обрабатывается в настоящий момент. Каждый цикл выполняется 16 раз, а так как каждый блок входного сообщения обрабатывается в четырех циклах, то каждый блок входного сообщения обрабатывается по схеме, показанной на, 64 раза. Если представить входной 512-битный блок в виде шестнадцати 32-битных слов, то каждое входное 32-битное слово используется четыре раза, по одному разу в каждом цикле, и каждый элемент таблицы Т, состоящей из 64 32-битных слов, используется только один раз. После каждого шага цикла происходит циклический сдвиг влево четырех слов A, B, C и D. На каждом шаге изменяется только одно из четырех слов буфера ABCD. Следовательно, каждое слово буфера изменяется 16 раз, и затем 17-ый раз в конце для получения окончательного выхода данного блока.
Можно суммировать алгоритм MD5 следующим образом:

MD0 = IV
MDq+1 = MDq + fI[Yq, fH[Yq, fG[Yq, fF[Yq, MDq]]]]
MD = MDL-1 

Где


IV - начальное значение буфера ABCD, определенное на шаге 3.

Yq - q-ый 512-битный блок сообщения.

L - число блоков в сообщении (включая поля дополнения и длины).

MD - окончательное значение дайджеста сообщения.

Алгоритм MD4

Алгоритм MD4 является более ранней разработкой того же автора Рона Ривеста. Первоначально данный алгоритм был опубликован в октябре 1990 г., незначительно измененная версия была опубликована в RFC 1320 в апреле 1992 г. Кратко рассмотрим основные цели MD4:

  1. Безопасность: это обычное требование к хэш-коду, состоящее в том, чтобы было вычислительно невозможно найти два сообщения, имеющие один и тот же дайджест.
  2. Скорость: программная реализация алгоритма должна выполняться достаточно быстро. В частности, алгоритм должен быть достаточно быстрым на 32-битной архитектуре. Поэтому алгоритм основан на простом множестве элементарных операций над 32-битными словами.
  3. Простота и компактность: алгоритм должен быть простым в описании и простым в программировании, без больших программ или подстановочных таблиц. Эти характеристики не только имеют очевидные программные преимущества, но и желательны с точки зрения безопасности, потому что для анализа возможных слабых мест лучше иметь простой алгоритм.
  4. Желательна little-endian архитектура: некоторые архитектуры процессоров (такие как линия Intel 80xxx) хранят левые байты слова в позиции младших адресов байта (little-endian). Другие (такие как SUN Sparcstation) хранят правые байты слова в позиции младших адресов байта (big endian). Это различие важно, когда сообщение трактуется как последовательность 32-битовых слов, потому что эти архитектуры имеют инверсное представление байтов в каждом слове. Ривест выбрал использование схемы little-endian для интерпретации сообщения в качестве последовательности 32-битных слов. Этот выбор сделан потому, что big-endian процессоры обычно являются более быстрыми.

Эти цели преследовались и при разработке MD5. MD5 является более сложным и, следовательно, более медленным при выполнении, чем MD4. Считается, что добавление сложности оправдывается возрастанием уровня безопасности. Главные различия между этими двумя алгоритмами состоят в следующем:

  1. MD4 использует три цикла из 16 шагов каждый, в то время как MD5 использует четыре цикла из 16 шагов каждый.
  2. В MD4 дополнительная константа в первом цикле не применяется. Аналогичная дополнительная константа используется для каждого из шагов во втором цикле. Другая дополнительная константа используется для каждого из шагов в третьем цикле. В MD5 различные дополнительные константы, Т [i], применяются для каждого из 64 шагов.
  3. MD5 использует четыре элементарные логические функции, по одной на каждом цикле, по сравнению с тремя в MD4, по одной на каждом цикле.
  4. В MD5 на каждом шаге текущий результат складывается с результатом предыдущего шага. Например, результатом первого шага является измененное слово А. Результат второго шага хранится в D и образуется добавлением А к циклически сдвинутому влево на определенное число бит результату элементарной функции. Аналогично, результат третьего шага хранится в С и образуется добавлением D к циклически сдвинутому влево результату элементарной функции. MD4 это последнее сложение не включает.
Усиление алгоритма в MD5

Алгоритм MD5 имеет следующее свойство: каждый бит хэш-кода является функцией от каждого бита входа. Комплексное повторение элементарных функций fF, fG, fH и fI обеспечивает то, что результат хорошо перемешан; то есть маловероятно, чтобы два сообщения, выбранные случайно, даже если они имеют явно похожие закономерности, имели одинаковый хэш-код. Считается, что MD5 является наиболее сильной хэш-функцией для 128-битного хэш-кода, то есть трудность нахождения двух сообщений, имеющих одинаковый дайджест, имеет порядок 264 операций. В то время, как трудность нахождения сообщения с данным дайджестом имеет порядок 2128 операций.
Два результата, тем не менее, заслуживают внимания. Показано, что используя дифференциальный криптоанализ, можно за разумное время найти два сообщения, которые создают один и тот же дайджест при использовании только одного цикла MD5. Подобный результат можно продемонстрировать для каждого из четырех циклов. Однако обобщить эту атаку на полный алгоритм MD5 из четырех циклов пока не удалось.

Существует способ выбора блока сообщения и двух соответствующих ему промежуточных значений дайджеста, которые создают одно и то же выходное значение. Это означает, что выполнение MD5 над единственным блоком из 512 бит приведет к одинаковому выходу для двух различных входных значений в буфере ABCD. Пока способа расширения данного подхода для успешной атаки на MD5 не существует.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика