RSA-PKCS1v15: принцип работы и риски

Алгоритм RSA основан на сложности факторизации больших чисел и работает с парой ключей: открытым (public key) и закрытым (private key). Открытый ключ используется для шифрования или проверки подписи, закрытый — для расшифрования или создания подписи.

Схема PKCS#1 v1.5 — это исторически одна из первых стандартизированных схем дополнения (padding) для RSA. Она применяется как в шифровании, так и в цифровых подписях, но имеет различия в формате в зависимости от назначения:

  • RSAES-PKCS1-v1_5 — для шифрования
  • RSASSA-PKCS1-v1_5 — для цифровых подписей

Padding необходим, поскольку «чистый» RSA детерминирован и уязвим к атакам. Дополнение добавляет случайность и структурирует данные перед операцией возведения в степень.


Формат блока при шифровании (RSAES-PKCS1-v1_5)

Перед шифрованием сообщение преобразуется в блок фиксированной длины, равной длине модуля RSA (например, 2048 бит = 256 байт):

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

Где:

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

Ключевые свойства:

  • Минимальная длина PS = 8 байт — защита от простых атак
  • Общая длина блока строго фиксирована
  • Наличие случайности в PS делает шифротекст непредсказуемым

Формат блока при подписи (RSASSA-PKCS1-v1_5)

Для подписи используется иной формат:

EM = 0x00 || 0x01 || PS || 0x00 || T

Где:

  • 0x01 — тип блока (подпись)
  • PS — последовательность байтов 0xFF
  • T — DER-кодированная структура, содержащая хэш и идентификатор алгоритма

Структура T включает:

  • OID алгоритма хэширования (например, SHA-256)
  • Сам хэш сообщения

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


Принцип работы в библиотеке jsrsasign

Библиотека jsrsasign предоставляет реализацию RSA с поддержкой PKCS#1 v1.5.

Шифрование

const rsa = new KJUR.crypto.Cipher();
const encrypted = rsa.encrypt("message", publicKey, "RSA");

Под капотом:

  1. Сообщение кодируется в байты

  2. Добавляется padding по PKCS#1 v1.5

  3. Выполняется операция:

    C = M^e mod n

Расшифрование

const decrypted = rsa.decrypt(encrypted, privateKey, "RSA");

Процесс:

  1. Выполняется:

    M = C^d mod n
  2. Проверяется структура padding

  3. Извлекается исходное сообщение

Подпись

const sig = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
sig.init(privateKey);
sig.updateString("data");
const signature = sig.sign();

Проверка подписи

sig.init(publicKey);
sig.updateString("data");
const isValid = sig.verify(signature);

Уязвимости PKCS#1 v1.5

Несмотря на широкое распространение, схема PKCS#1 v1.5 имеет ряд серьёзных криптографических проблем.

Атака Блейхенбахера (Bleichenbacher Attack)

Одна из наиболее известных атак на RSAES-PKCS1-v1_5, опубликованная в 1998 году.

Суть:

  • Атакующий отправляет множество модифицированных шифротекстов
  • Анализирует ответы сервера (например, ошибка padding или успешная расшифровка)
  • Постепенно восстанавливает исходное сообщение

Атака относится к классу adaptive chosen-ciphertext attack (CCA2).

Причина уязвимости:

  • Различимая реакция на ошибки padding
  • Структурированность формата 0x00 || 0x02

Padding Oracle

Если система сообщает, корректен ли padding, возникает «оракул»:

  • padding valid → одна ветка
  • padding invalid → другая ветка

Это позволяет по частям восстанавливать сообщение.

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


Отсутствие семантической безопасности

PKCS#1 v1.5 не гарантирует полной защиты от:

  • повторного воспроизведения (replay attack)
  • анализа структуры сообщений

Современные требования требуют IND-CCA2 безопасности, которой эта схема не обеспечивает.


Ограничения на длину сообщения

Максимальная длина сообщения:

k - 11 байт

Где k — длина ключа в байтах.

Пример:

  • 2048 бит → 256 байт
  • Максимум сообщения: 256 - 11 = 245 байт

Причина:

  • 2 байта на заголовок
  • минимум 8 байт padding
  • 1 байт-разделитель

Практические риски при использовании

  1. Использование в TLS (устаревшие версии) Ранние версии TLS (до 1.2) применяли PKCS#1 v1.5 → уязвимость к Bleichenbacher

  2. Неправильная обработка ошибок

    • разные сообщения об ошибках
    • различия во времени выполнения
  3. Отсутствие защиты от повторных атак

    • повторное использование шифротекста
  4. Небезопасные реализации

    • отсутствие константного времени
    • утечки через побочные каналы

Современные альтернативы

RSA-OAEP (Optimal Asymmetric Encryption Padding)

Рекомендуется вместо PKCS#1 v1.5 для шифрования.

Преимущества:

  • доказанная безопасность (в модели случайного оракула)
  • защита от CCA2 атак
  • использование хэш-функций и маскирования (MGF1)

В jsrsasign:

const encrypted = rsa.encrypt("message", publicKey, "RSAOAEP");

RSA-PSS (Probabilistic Signature Scheme)

Замена RSASSA-PKCS1-v1_5 для подписей.

Особенности:

  • случайный padding
  • высокая криптостойкость
  • защита от подделки подписи

Причины сохранения PKCS#1 v1.5 в системах

  • обратная совместимость
  • поддержка устаревших протоколов
  • наличие в стандартах (X.509, S/MIME, старые TLS)

Тем не менее, в новых системах использование не рекомендуется.


Рекомендации по безопасному использованию

Если использование PKCS#1 v1.5 неизбежно:

  • скрывать различия в ошибках
  • использовать константное время обработки
  • не раскрывать детали padding
  • применять дополнительные уровни защиты (например, симметричное шифрование поверх RSA)

В jsrsasign:

  • избегать явной обработки padding
  • использовать встроенные методы
  • по возможности переключаться на OAEP/PSS

Внутренний механизм проверки padding

При расшифровке:

  1. Проверяется первый байт (0x00)
  2. Проверяется тип (0x02)
  3. Ищется первый 0x00 после PS
  4. Извлекается сообщение

Любое отклонение:

  • ошибка padding
  • потенциальный источник утечки

Криптографическая модель

PKCS#1 v1.5 не удовлетворяет:

  • IND-CCA2 (indistinguishability under adaptive chosen ciphertext attack)

Но обеспечивает:

  • базовую защиту от случайных атак
  • совместимость с историческими системами

Итоговое положение в экосистеме

PKCS#1 v1.5 — важный этап в развитии криптографии:

  • широко внедрён
  • хорошо изучен
  • имеет известные уязвимости

Современные системы стремятся к отказу от него в пользу более безопасных схем, но понимание принципов его работы остаётся критически важным для анализа безопасности и поддержки легаси-инфраструктуры.