Ограничение на размер шифруемых данных

Алгоритм RSA основан на математических операциях над большими числами фиксированного размера, определяемого длиной ключа. Это накладывает жёсткое ограничение на объём данных, который может быть зашифрован за одну операцию. В Jsrsasign это проявляется особенно явно, поскольку библиотека предоставляет низкоуровневые интерфейсы к RSA без автоматического разбиения данных.

Максимальный размер шифруемого блока определяется длиной ключа и схемой заполнения (padding).

Для RSA с PKCS#1 v1.5:

  • максимальный размер данных = keySizeInBytes - 11

Для RSA-OAEP:

  • размер зависит от используемой хэш-функции
  • формула: keySizeInBytes - 2 * hashLen - 2

Пример для 2048-битного ключа:

  • 2048 бит = 256 байт
  • PKCS#1 v1.5: максимум 245 байт
  • OAEP с SHA-1: максимум 214 байт
  • OAEP с SHA-256: максимум 190 байт

Любое превышение приводит к ошибке шифрования или некорректному результату.


Причина ограничения на уровне RSA

RSA не предназначен для обработки произвольных объёмов данных. Его математическая модель работает с числом m, которое должно быть меньше модуля n:

  • ciphertext = m^e mod n

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

Padding-схемы добавляют структурные данные, необходимые для безопасности:

  • случайные байты
  • контрольные структуры
  • идентификаторы алгоритмов

Эти данные уменьшают доступный объём полезной нагрузки.


Поведение Jsrsasign при превышении размера блока

В библиотеке Jsrsasign RSA реализован через объект RSAKey. При вызове методов шифрования:

  • encrypt(plaintext)
  • decrypt(ciphertext)

входные данные преобразуются в байтовую строку и проверяются на допустимый размер.

При превышении лимита возможны сценарии:

  • возврат null
  • выброс ошибки (в зависимости от сборки и режима)
  • некорректное усечение входных данных при неправильной обработке типов

Jsrsasign не выполняет автоматическое разбиение строки на блоки. Это оставляется на уровень приложения.


Практическое ограничение при работе с текстом

Строки в JavaScript часто кодируются в UTF-8 или UTF-16, что влияет на реальный размер данных.

Пример:

  • ASCII символ = 1 байт
  • кириллица UTF-8 = 2 байта
  • эмодзи = 4 байта

Таким образом, строка длиной 200 символов может превышать лимит RSA-2048 даже без визуального увеличения.

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


Подход к обработке больших данных: гибридное шифрование

Практическое применение RSA в Jsrsasign почти всегда строится на гибридной модели:

  • симметричный алгоритм шифрует основной объём данных
  • RSA используется только для шифрования ключа

Типовая схема:

  1. Генерация случайного симметричного ключа (AES)
  2. Шифрование данных AES
  3. Шифрование AES-ключа через RSA
  4. Передача двух компонентов: encryptedData + encryptedKey

Пример реализации гибридного подхода

Jsrsasign предоставляет инструменты через KJUR.crypto.Cipher и KEYUTIL.

Пример логики:

// генерация AES ключа
var aesKey = KJUR.crypto.Cipher.generateRandomKey(256);

// шифрование данных AES
var encryptedData = KJUR.crypto.Cipher.encrypt(data, aesKey, "AES");

// загрузка RSA публичного ключа
var rsa = KEYUTIL.getKey(publicKeyPem);

// шифрование AES ключа через RSA
var encryptedKey = rsa.encrypt(aesKey);

В этой схеме RSA обрабатывает только короткую строку ключа AES, что укладывается в допустимый диапазон.


Разбиение данных на блоки (chunking)

При необходимости использования RSA напрямую для больших данных применяется ручное разбиение.

Алгоритм:

  • вычисление максимального блока
  • разбиение строки на сегменты
  • последовательное шифрование каждого блока
  • объединение результата

Пример логики:

var maxBlock = 245; // для RSA 2048 PKCS#1 v1.5
var blocks = [];

for (var i = 0; i < data.length; i += maxBlock) {
    var chunk = data.substring(i, i + maxBlock);
    blocks.push(rsa.encrypt(chunk));
}

Результирующий массив содержит набор независимых RSA-шифрованных блоков.


Ограничения chunking-подхода

Разбиение данных через RSA приводит к ряду проблем:

  • значительное снижение производительности
  • увеличение размера выходных данных (каждый блок = полный RSA-шифртекст)
  • сложность восстановления и проверки целостности
  • отсутствие встроенной поддержки в Jsrsasign

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


Размер выходных данных RSA

RSA увеличивает размер данных до фиксированной длины ключа:

  • 2048-битный ключ → 256 байт на блок
  • 4096-битный ключ → 512 байт на блок

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

Это приводит к экспоненциальному росту данных при chunking.


Различие между шифрованием и подписью

Важно различать ограничения шифрования и цифровой подписи.

При RSA-подписи:

  • данные хешируются (SHA-256, SHA-1 и др.)
  • шифруется только хеш

Таким образом:

  • ограничение на размер входных данных практически отсутствует
  • подпись всегда фиксированной длины (размер ключа)

Jsrsasign реализует подписи через:

  • KJUR.crypto.Signature

Практическое использование Jsrsasign в условиях ограничений

Архитектура приложений обычно учитывает следующие принципы:

  • RSA используется только для ключей
  • данные шифруются симметрично
  • chunking применяется только в исключительных случаях
  • контроль размера выполняется до шифрования

Проверка размера перед операцией:

function checkSize(data, keySizeBytes) {
    return data.length <= (keySizeBytes - 11);
}

Типичные ошибки при работе с ограничениями RSA

На практике часто встречаются следующие проблемы:

  • попытка зашифровать JSON-объект целиком
  • игнорирование UTF-8 увеличения размера
  • использование RSA вместо AES
  • отсутствие контроля длины входных данных
  • неправильный выбор padding-схемы

Jsrsasign не выполняет автоматическую защиту от этих сценариев, поэтому логика контроля остаётся на уровне приложения.


Влияние выбора padding на совместимость

Jsrsasign поддерживает разные схемы:

  • PKCS#1 v1.5
  • RSA-OAEP

Разные реализации серверов могут требовать строго определённый режим.

Несовместимость проявляется в:

  • ошибках расшифровки
  • различии максимального размера блока
  • различии структуры зашифрованного сообщения

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


Итоговая модель работы с ограничением размера

Работа с RSA в Jsrsasign всегда подчиняется одной из двух моделей:

  • краткие данные напрямую через RSA (до лимита)
  • гибридное шифрование для любых объёмов

Любые попытки обойти ограничение увеличением ключа приводят только к росту стоимости вычислений и размера данных без изменения фундаментального лимита структуры RSA.