Уязвимости RSA PKCS#1 v1.5 и почему стоит использовать OAEP

RSA PKCS#1 v1.5 долгое время был стандартным способом упаковки данных перед асимметричным шифрованием. Его задача — подготовить сообщение так, чтобы оно могло быть безопасно обработано математикой RSA, которая сама по себе работает только с числами фиксированной длины.

Формат выглядит как структура:

EM = 0x00 || 0x02 || PS || 0x00 || M

где:

  • 0x00 0x02 — фиксированные байты, обозначающие тип шифрования
  • PS — паддинг из случайных байтов (padding string)
  • 0x00 — разделитель
  • M — исходное сообщение

Ключевой элемент здесь — паддинг PS, который заполняется случайными значениями и должен быть достаточно длинным, чтобы сообщение не помещалось в исходный блок без расширения.

Именно эта конструкция стала источником целого класса атак.


Почему PKCS#1 v1.5 оказался уязвимым

Главная проблема PKCS#1 v1.5 заключается не в математике RSA, а в том, как реализована обработка ошибок при расшифровке.

Padding oracle

Если система при расшифровке ведёт себя по-разному в зависимости от корректности паддинга (например, возвращает разные ошибки или различается время ответа), атакующий получает так называемый oracle padding — побочный канал информации.

На основе этого можно восстановить зашифрованный текст, не имея приватного ключа.


Атака Bleichenbacher (1998)

Одной из самых известных атак на PKCS#1 v1.5 стала атака Bleichenbacher.

Её суть:

  1. Атакующий отправляет модифицированные ciphertext’ы на сервер.
  2. Сервер сообщает, корректен ли паддинг.
  3. Через множество запросов можно математически сузить диапазон возможных значений plaintext.
  4. В итоге сообщение полностью восстанавливается.

Эта атака показала, что даже небольшая утечка информации о корректности формата делает RSA PKCS#1 v1.5 принципиально небезопасным в интерактивных протоколах.


Реальные последствия для протоколов

После публикации атак стало ясно, что PKCS#1 v1.5 особенно опасен в следующих сценариях:

  • TLS (старые версии SSL/TLS)
  • API с RSA-шифрованием токенов
  • серверы, возвращающие разные ошибки дешифрования
  • любые системы, где есть обратная связь о корректности расшифровки

Даже если ошибки не отображаются напрямую, различия во времени ответа могут быть достаточны для атаки.


Почему проблема не исчезла мгновенно

Несмотря на известность уязвимости, PKCS#1 v1.5 продолжал использоваться по нескольким причинам:

  • обратная совместимость с legacy-системами
  • простота реализации
  • широкая поддержка в старых криптографических библиотеках

Однако криптография показывает жесткое правило: устаревшие схемы с доказанными побочными каналами нельзя «починить» настройками — их нужно заменять.


OAEP: современная альтернатива

Optimal Asymmetric Encryption Padding (OAEP) был разработан как более безопасная схема упаковки данных для RSA.

В отличие от PKCS#1 v1.5, OAEP использует не просто паддинг, а криптографически обоснованную конструкцию с хэш-функциями и маскирующими генераторами.

Упрощённо структура выглядит так:

  • сообщение смешивается с случайностью
  • применяется mask generation function (MGF)
  • результат становится полностью непредсказуемым
  • обратное восстановление без приватного ключа математически устойчиво

Ключевое отличие OAEP от PKCS#1 v1.5

1. Отсутствие oracle-структуры

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

2. Семантическая безопасность

При корректной реализации OAEP обеспечивает IND-CCA безопасность (indistinguishability under chosen ciphertext attack).

3. Хэширование и маскирование

Использование хэшей делает структуру сообщения нечитаемой без ключа даже частично.


Почему OAEP устойчив к Bleichenbacher-подобным атакам

Ключевая идея OAEP — устранить возможность частичной проверки корректности структуры ciphertext.

В PKCS#1 v1.5 можно определить:

  • корректен ли паддинг
  • где начинается сообщение
  • соответствует ли структура шаблону

В OAEP:

  • любое отклонение превращается в одинаково «случайную» ошибку
  • атакующий не получает градиента информации
  • отсутствует возможность итеративного сужения диапазона

RSA в современной криптографии и роль OAEP в JavaScript

В экосистеме JavaScript криптографические библиотеки (в том числе JOSE) используют RSA в основном в двух контекстах:

  • шифрование ключей (JWE)
  • обёртка симметрических ключей

Именно здесь выбор между PKCS#1 v1.5 и OAEP критичен.

В современных спецификациях JOSE:

  • RSA1_5 — устаревший и небезопасный режим
  • RSA-OAEP — рекомендуемый вариант
  • RSA-OAEP-256 — усиленная версия с SHA-256

Проблемы RSA1_5 в прикладных системах

Даже если протокол формально защищён, использование PKCS#1 v1.5 приводит к рискам:

1. Адаптивные атаки

Злоумышленник может подбирать ciphertext и наблюдать поведение сервера.

2. Утечки через ошибки

Разные типы ошибок дешифрования становятся информационным каналом.

3. Совместимость с устаревшими API

Многие старые системы до сих пор используют RSA1_5, что заставляет разработчиков поддерживать небезопасный режим.


Практическое сравнение в контексте JOSE

В библиотеке JOSE выбор алгоритма влияет напрямую на безопасность JWE:

  • alg: RSA1_5

    • допускает padding oracle классы атак
    • не рекомендуется использовать
  • alg: RSA-OAEP

    • современный безопасный стандарт
    • используется в новых системах
  • alg: RSA-OAEP-256

    • усиленная криптографическая стойкость
    • предпочтительный вариант при новых интеграциях

Почему переход на OAEP обязателен

Криптографическая безопасность RSA сегодня определяется не размером ключа, а тем, как используется padding.

PKCS#1 v1.5:

  • исторически важен
  • но структурно уязвим к активным атакам

OAEP:

  • разработан с учётом активного противника
  • формально доказуемая стойкость в модели chosen ciphertext attack

Итоговая техническая картина

RSA без корректного padding — математически корректен, но криптографически небезопасен. PKCS#1 v1.5 оказался переходным стандартом, который не выдержал требований активных атакующих моделей.

OAEP стал ответом на фундаментальную проблему: необходимость скрыть структуру сообщения так, чтобы никакой побочный канал не позволял извлечь информацию о plaintext даже при контролируемых ошибках дешифрования.