Завершаем решение cryptopals. В этой части рассмотрим блоки заданий 5 и 6, которые посвящены криптографии с открытым ключом.
Первая часть
Вторая часть
Третья часть
Блок 5: Diffie-Hellman and friends
Темы: Протокол Диффи-Хеллмана, SRP
Ссылка: https://cryptopals.com/sets/5
Задание 33: Implement Diffie-Hellman
Подготовительное задание, которое знакомит с протоколом Диффи-Хеллмана для выработки общего сессионного ключа.
Задание 34: Implement a MITM key-fixing attack on Diffie-Hellman with parameter injection
Задание демонстрирует вариант атаки «человек посередине» в протоколе Диффи-Хеллмана.
Рассмотрим, какой общий ключ получается в результате. При нормальном выполнении протокола , но из-за противника посередине A думает, что , поэтому
В этом случае сессионный ключ имеет предсказуемое значение, благодаря чему M может расшифровывать сообщения.
Задание 35: Implement DH with negotiated groups, and break with malicious "g" parameters
Задание демонстрирует, что происходит с протоколом Диффи-Хеллмана при неудачном выборе параметра .
Генерация сессионного ключа для участника A:
, тогда
, тогда
, тогда или 1
Во всех случаях значение сессионного ключа легко предсказуемо.
Задание 36: Implement Secure Remote Password (SRP)
Подготовительное задание, нужно реализовать протокол Secure Remote Password.
Задание 37: Break SRP with a zero key
Задание демонстрирует уязвимость протокола SRP в случае, если клиент использует значение .
В этом случае , и ключ будет иметь предсказуемое значение .
Задание 38: Offline dictionary attack on simplified SRP
Приведённый в задании «упрощённый» протокол SRP отличается от оригинального главным образом тем, что значение не зависит от , а значит и от пароля. Это позволяет атакующему посередине использовать произвольное в качестве ответа на запрос клиента, а затем в режиме офлайн осуществлять перебор пароля по словарю.
Задание 39: Implement RSA
Подготовительное задание, нужно реализовать криптосистему RSA.
Задание 40: Implement an E=3 RSA Broadcast attack
Задание демонстрирует Broadcast attack на систему RSA с небольшим .
Если одно и то же сообщение было зашифровано на трёх различных публичных ключах RSA, то:
Это система линейных сравнений по модулю, которую можно решить с помощью Китайской теоремы об остатках и найти . Извлекая кубический корень из полученного решения, получаем исходное сообщение.
Блок 6: RSA and DSA
Тема: Атаки на RSA и DSA
Ссылка: https://cryptopals.com/sets/6
Задание 41: Implement unpadded message recovery oracle
Задание демонстрирует мультипликативное свойство RSA:
Если , то
Это свойство можно использовать, чтобы получить от сервера подпись для сообщения, которое напрямую не передавалось. По сути это простой протокол слепой подписи.
Задание 42: Bleichenbacher's e=3 RSA Attack
Задание посвящено атаке Bleichenbacher на PKCS1.5 RSA с .
Формат сообщения PKCS1.5
Cообщение PKCS1.5 имеет вид вид:
0x00 0x01 0xff 0xff ... 0xff 0xff 0x00 ASN HASH
, где
ASN — служебная информация, определяющая хеш-функцию
HASH — хеш исходного сообщения
Длина сообщения в байтах должна быть равна длине модуля (это обеспечивается нужным количеством байтов 0xff
).
Подпись сообщения
Подписанный пакет формируется так:
Пакет представляется в виде числа
Подписывается RSA:
Проверка подписи
При проверке подписи сообщения подпись снимается , затем проверяется хеш исходного сообщения.
Атака
Атака становится возможной из-за ошибки при реализации разбора сообщения.
Алгоритм разбора с ошибкой:
Найти байты
0x00, 0x01
Найти следующий за ними байт
0x00
Разобрать
ASN
, узнать длину хешаПолучить нужное количество байт хеша
Сверить хеш
Ошибка состоит в том, что не проверяется ни длина сообщения, ни корректность заполнения. Поэтому сообщения вида 0x00 0x01 0x00 ASN.1 HASH SOMEBYTES
также будут успешно разобраны парсером.
Чтобы подделать подпись, необходимо получить такое сообщение, чтобы при возведении в куб оно имело вид 0x00 0x01 ... 0x00 ASN.1 HASH SOMEBYTES
.
Составляем сообщение
0x00 0x01 0x00 ASN.1 HASH 0x00...0x00
Извлекаем из него кубический корень
Задание 43: DSA key recovery from nonce
Задание состоит из двух частей:
Первая часть — реализация протокола DSA
Вторая часть демонстрирует, что нельзя использовать предсказуемые значения — это приводит к раскрытию секретного ключа
Если известно, то секретный ключ легко вычислить:
В задании лежит в отрезке , поэтому находим его перебором.
Внимание: в задании и указаны в десятичной системе счисления, в то время как остальные числа — в шестнадцатеричной.
Задание 44: DSA nonce recovery from repeated nonce
Задание демонстрирует, что нельзя использовать повторяющиеся значения для различных сообщений при использовании подписи DSA — это приводит к раскрытию секретного ключа.
Если одинаковые, то также будут одинаковые. Находим в файле два сообщения с одинаковым
Рассчитываем
Рассчитываем по известному , как в Задании 43
Задание 45: DSA parameter tampering
Задание показывает, что важно тщательно проверять параметры, которые используются в подписи DSA.
Случай :
В этом случае проверка любой подписи для любого сообщения будет верной, потому что
И всегда совпадает сСлучай :
В этом случае можно составить такую подпись, которая будет подходить к любому тексту:
— любое число
Тогда при проверке:
Задание 46: RSA parity oracle
Дан оракул, который определяет чётность зашифрованного с помощью RSA числа. Используя этот оракул, нужно расшифровать число. Задание игрушечное, но очень полезное для понимания следующего.
Пусть — исходное число
— зашифрованное число
Мы можем получить зашифрованный текст для сообщения :
Подаём это сообщение на вход оракулу:
Если ответ, что число нечётное, значит сообщение превосходит (так как — нечётное, остаток без превышения должен быть нечётным), а значит
Если ответ чётное, значит
Изначально известно, что . Повторяя эту операцию для , ,... находим .
Задание 47-48: Bleichenbacher's PKCS 1.5 Padding Oracle
Это задание сложнее, чем все остальные вместе взятые. Требуется реализовать атаку, описанную в статье «Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS #1», Daniel Bleichenbacher.
Формат PKCS
Используется RSA с параметрами , , . Длина в байтах равна .
Структура сообщения PKCS:
0x00 0x02 PAD 0x00 DATA
, где:
0x00 0x02
— фиксированное начало
PAD
— заполнение случайными ненулевыми байтами
0x00
— нулевой байт, признак начала данных
DATA
— данные
Общая длина сообщения равна в точности .
Сообщение превращается в целое число и шифруется .
Описание атаки
Атака возможна из-з недостатка реализации расшифровки и разбора сообщения PKCS. Она заключается в том, что парсер сразу выдаёт какую-то особую ошибку, если первые два байта сообщения не равны 0x00 0x02
. Это позволяет атакующему получить информацию о первых байтах сообщения.
Обозначим 0x00 0x01 0x00 ... 0x00
, в десятичной форме
Так как в сообщении первые два байта равны 0x00 0x02
, то известно, что
, так как имеет вид
0x00 0x02 0x00 ... 0x00
, так как имеет вид
0x00 0x03 0x00 ... 0x00
Зная , мы можем для некоторого составить сообщение
Если сообщение не вызывает ошибки, то первые два байта в равны 0x00 0x02
, значит
, следовательно
Что даёт новые ограничения для . Эти ограничения уточняют исходное ограничение
Повторяя этот процесс, получаем единственно возможное значение .
Решение
Полагаем . Ищем такое, что сообщение не вызовет ошибки.
Верна оценка , . И чтобы должно выполняться — это значение используем как отправную точку
Получаем ограничения для :
Строим пересечение полученных ограничений с текущими ограничениями
Далее возможны три случая:
состоит из более чем одного отрезка. В этом случае мы находим значение , получаем ограничения для и переходим на шаг 3.
состоит ровно из одного отрезка, который состоит из одной точки. Тогда найдено
состоит ровно из одного отрезка . Тогда применяется оптимизация поиска: находим такое, что (при этом ). Получаем ограничения для и переходим на шаг 3.
Код решений на python: https://github.com/seregablog/cryptopals
Больше интересного у меня в Телеграм-канале