Апокриф 09

RSA: математические ловушки и атаки на реализацию

RSA: математические ловушки и атаки на реализацию

RSA держится на одной асимметрии: умножить два простых числа легко, разделить произведение — нет. Всё остальное — детали реализации, и именно в них живут атаки. За тридцать лет RSA ломали не через факторизацию 2048-битного модуля, а через то, что кто-то взял маленькую экспоненту, забыл дополнение, переиспользовал простые числа или оставил оракул в обработке ошибок.

Тема идёт от конструкции к ловушкам. Сначала честная схема: генерация ключей, шифрование, подпись, китайская теорема об остатках. Потом — почему «учебный RSA» (без дополнения) нестоек: он мультипликативен, детерминирован и позволяет перемножать шифртексты. Затем четыре классические атаки: малая экспонента без дополнения, широкая атака Хастада по китайской теореме, общий модуль с двумя экспонентами и общий простой множитель у двух модулей. Завершается разбор дополнений: PKCS#1 v1.5 и оракул Блейхенбахера, OAEP и правило «не расшифровывать вслепую».

Конструкция RSA

Ключи

Выбираются два простых числа p и q, модуль n = p·q, функция Эйлера φ(n) = (p−1)(q−1). Открытая экспонента e взаимно проста с φ(n), закрытая d = e^(−1) mod φ(n). Открытый ключ — (n, e), закрытый — (n, d) плюс простые числа для ускорения 1.

Шифрование: c = m^e mod n. Расшифрование: m = c^d mod n. Корректность следует из теоремы Эйлера: m^(ed) = m^(1 + kφ(n)) = m mod n для m, взаимно простого с n; для остальных случаев работает китайская теорема об остатках.

Подпись и КТО

Подпись — та же операция с закрытым ключом: s = H(m)^d mod n, проверка — s^e = H(m) mod n. Дополнение обязательно, и схемы для шифрования и подписи разные: для шифрования — PKCS#1 v1.5 (устаревшее, но всё ещё встречается) или OAEP, для подписи — PKCS#1 v1.5 или PSS. PSS для шифрования не применяется, OAEP — для подписи. Подпись «сырого» хеша без структуры ломается мультипликативностью 2.

Китайская теорема об остатках ускоряет расшифрование в четыре раза: вместо одного возведения в степень по модулю n выполняются два по модулям p и q, а результат собирается обратно. Это стандартная оптимизация во всех библиотеках.

Атака на сбой при КТО

Ускорение через КТО создаёт отдельную уязвимость — атаку Белкора. Если при вычислении m_p = c^{d_p} mod p или m_q = c^{d_q} mod q происходит сбой (перегрев, пониженное напряжение, облучение, ошибка в оборудовании), то одна из половин результата оказывается неверной, а сборка по КТО даёт значение s, для которого s^e ≠ c mod n. При этом s^e − c делится на один из простых множителей и не делится на другой, поэтому gcd(s^e − c mod n, n) мгновенно выдаёт p или q — и весь закрытый ключ. Защита: проверять результат возведения в степень до выдачи (s^e = c mod n), использовать проверяемые схемы дополнения и защиту от сбоев на уровне платформы. Это пример того, что оптимизация реализации — самостоятельная поверхность атаки, а не деталь.

Почему учебный RSA нестоек

Детерминированность

c = m^e mod n — детерминированная функция. Одинаковые сообщения дают одинаковые шифртексты, и противник может проверить гипотезу о содержимом, просто зашифровав её открытым ключом. Это нарушение семантической стойкости, и лечится оно рандомизированным дополнением.

Мультипликативность

(m_1·m_2)^e = m_1^e · m_2^e mod n. Значит, c_1·c_2 — валидный шифртекст произведения. Противник, зная c = m^e, может вычислить c·2^e = (2m)^e и получить шифртекст удвоенного сообщения, не зная ключа. На рисунке 1 показана схема.

Мультипликативность RSA
Рисунок 1. Без дополнения шифртекст можно умножить на factor^e и получить шифртекст message·factor

Именно поэтому в реальных схемах перед шифрованием укладывается структурированное дополнение, а проверка при расшифровании строгая. Учебный RSA годится только для демонстрации математики.

Малая экспонента и атака Хастада

e = 3 без дополнения

Если e = 3 и сообщение короткое (m^3 < n), возведение в куб не «заворачивается» по модулю, и c = m^3 как целое. Тогда m = c^(1/3) вычисляется целочисленным корнем — без факторизации. Защита: либо e ≥ 65537, либо дополнение, удлиняющее сообщение до размера модуля 5.

Широкая атака Хастада

Пусть одно сообщение отправлено e получателям с разными модулями n_i и одной экспонентой e. Тогда c_i = m^e mod n_i, и по китайской теореме об остатках восстанавливается m^e mod (n_1·…·n_e). Если m^e меньше произведения модулей, корень извлекается точно 4. Схема на рисунке 2.

Условия атаки нужно перечислять полностью, иначе она выглядит применимой всегда, а это не так: одно и то же сообщение m (или разные сообщения, но с известным линейным соотношением), одна и та же малая экспонента e у всех получателей, попарно взаимно простые модули n_i — иначе китайская теорема даёт не m^e mod N, а систему с ограничениями, — и отсутствие рандомизированного дополнения. Если выполнено хотя бы одно из условий «нет», атака не работает: разные дополнения дают разные m_i, и общее m из них не собирается.

Широкая атака Хастада
Рисунок 2. Перехват e шифртекстов одного сообщения: CRT собирает m^e, целый корень даёт m

Защита — рандомизированное дополнение: даже одно и то же сообщение даёт разные m_i, и атака рассыпается.

Общий модуль и общий простой

Общий модуль

Если два пользователя используют один n, но разные e_1, e_2, противник, зная c_1 = m^(e_1) и c_2 = m^(e_2), находит a·e_1 + b·e_2 = 1 расширенным алгоритмом Евклида и вычисляет c_1^a·c_2^b = m mod n. Никакой факторизации не нужно. Тот же приём работает и тогда, когда известно часть сообщения: методы Копперсмита находят малые корни полиномиальных сравнений 7. Защита: у каждого свой модуль, и это проверяется при генерации.

Общий простой множитель

Если у двух модулей есть общий простой множитель, gcd(n_1, n_2) мгновенно даёт его, а значит, и разложение обоих. При плохом генераторе это не редкость: исследование 2012 года нашло десятки тысяч таких пар в Интернете 6. Проверка проста: при генерации ключей нужно использовать качественный источник случайности и проверять gcd с уже выданными модулями.

Ферма для близких простых

Если p и q близки, n = a^2 − b^2, где a = (p+q)/2, и перебор a от √n находит разложение за несколько шагов. Защита — генерировать простые независимо, а не «рядом».

Дополнение и оракул Блейхенбахера

PKCS#1 v1.5

Дополнение PKCS#1 v1.5: 00 02 || случайные ненулевые байты || 00 || сообщение. Оно рандомизирует шифртекст, но проверка при расшифровании имеет особенность: сервер должен решить, корректен ли формат. Если он сообщает об ошибке по-разному — «плохое дополнение» против «плохой формат», — возникает оракул.

Атака

Блейхенбахер показал, что одного бита «дополнение корректно» достаточно, чтобы расшифровать любой шифртекст за несколько тысяч запросов 3. Атака работает с интервалами: каждый ответ сужает множество возможных m, и после достаточного числа запросов остаётся одно значение. Именно так ломали SSL в 1998 году и позже — реализации в библиотеках и на смарт-картах.

Защита

OAEP заменяет v1.5: дополнение строится через две хеш-функции и проверяется целиком, а ошибка обработки дополнения неотличима от ошибки формата. Плюс правило: не расшифровывать данные, пришедшие от противника, без проверки целостности на уровне протокола; использовать постоянное время и единый ответ 8.

Итоги темы

  • RSA стоек как конструкция, но ломается на деталях реализации.
  • Без дополнения схема детерминирована и мультипликативна.
  • Малая экспонента без дополнения даёт целый корень; Хастад собирает m^e по CRT.
  • Общий модуль ломается расширенным Евклидом, общий простой — одним gcd.
  • Близкие простые разлагаются методом Ферма.
  • PKCS#1 v1.5 с оракулом — атака Блейхенбахера; OAEP и единообразные ошибки закрывают её.

Литература

  1. Rivest R., Shamir A., Adleman L. A Method for Obtaining Digital Signatures and Public-Key Cryptosystems. 1978. — исходная статья RSA.
  2. RFC 8017: PKCS #1: RSA Cryptography Specifications Version 2.2. 2016. — OAEP, PSS, v1.5 и требования к проверкам.
  3. Bleichenbacher D. Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS #1. CRYPTO 1998. — атака на оракул дополнения.
  4. Håstad J. Solving Simultaneous Modular Equations of Low Degree. SIAM Journal on Computing, 1988. — широкая атака на малую экспоненту.
  5. Boneh D. Twenty Years of Attacks on the RSA Cryptosystem. Notices of the AMS, 1999. — обзор атак и их причин.
  6. Lenstra A., Hughes J., Augier M., Bos J., Kleinjung T., Wachter C. Ron was Wrong, Whit is Right. 2012. — общие простые множители в реальных ключах.
  7. Coppersmith D. Small Solutions to Polynomial Equations, and Low Exponent RSA Vulnerabilities. 1997. — атаки на частично известное сообщение.
  8. Manger J. A Chosen Ciphertext Attack on RSA Optimal Asymmetric Encryption Padding (OAEP). CRYPTO 2001. — почему OAEP тоже требует аккуратной обработки ошибок.