Алгоритмы шифрования содержимого

Симметричное шифрование в Jsrsasign строится вокруг использования блочных алгоритмов, где один и тот же секретный ключ применяется и для шифрования, и для расшифрования данных. Основу составляют AES и, в более старых сценариях, DES/3DES. В современных реализациях предпочтение практически всегда отдается AES как более устойчивому и производительному варианту.

В библиотеке Jsrsasign симметричные операции выполняются через объект KJUR.crypto.Cipher, который инкапсулирует логику работы с ключами, режимами и дополнением (padding).

Пример базового шифрования AES:

var data = "секретное сообщение";
var password = "mySecretKey";

var encrypted = KJUR.crypto.Cipher.encrypt(data, password, "AES");
var decrypted = KJUR.crypto.Cipher.decrypt(encrypted, password, "AES");

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


Симметричные алгоритмы в Jsrsasign поддерживают различные режимы работы блоков:

  • ECB (Electronic Codebook) — простейший режим, где каждый блок шифруется отдельно
  • CBC (Cipher Block Chaining) — блоки связаны цепочкой через IV
  • CFB/OFB — потокоподобные режимы для частичной обработки данных

На практике наиболее часто используется CBC, поскольку он обеспечивает баланс между безопасностью и простотой реализации.

При использовании CBC обязательно наличие вектора инициализации (IV):

var cipher = new KJUR.crypto.Cipher({
    alg: "AES",
    mode: "CBC",
    iv: "00112233445566778899aabbccddeeff"
});

var enc = cipher.encrypt("plaintext", "password");

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


Асимметричное шифрование RSA

RSA в Jsrsasign используется для защиты небольших объемов данных, чаще всего — ключей симметричного шифрования. Основная особенность RSA заключается в разделении ключей:

  • открытый ключ — для шифрования
  • закрытый ключ — для расшифрования

Jsrsasign предоставляет утилиты KEYUTIL для работы с ключами в формате PEM.

var pubKey = KEYUTIL.getKey(pubPEM);
var enc = pubKey.encrypt("secret data");

Расшифрование выполняется через приватный ключ:

var privKey = KEYUTIL.getKey(privPEM, "password");
var dec = privKey.decrypt(enc);

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


Гибридное шифрование

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

Схема выглядит следующим образом:

  1. Генерируется случайный AES-ключ
  2. Данные шифруются AES
  3. AES-ключ шифруется RSA
  4. Оба результата передаются вместе

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

var aesKey = KJUR.crypto.Util.getRandomHexOfNbytes(16);

var encData = KJUR.crypto.Cipher.encrypt(message, aesKey, "AES");

var rsa = KEYUTIL.getKey(pubPEM);
var encKey = rsa.encrypt(aesKey);

На стороне получателя сначала расшифровывается ключ RSA, затем используется AES-дешифрование.


PKCS#7 и CMS EnvelopedData

Jsrsasign поддерживает стандарты криптографических сообщений PKCS#7 / CMS, которые используются в корпоративных системах и инфраструктуре PKI.

Объект KJUR.asn1.cms.EnvelopedData позволяет формировать зашифрованные контейнеры, содержащие:

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

Создание CMS EnvelopedData:

var cms = new KJUR.asn1.cms.EnvelopedData({
    content: "Hello world",
    certs: [certPEM],
    cipher: "aes256"
});

var result = cms.getContentInfo();

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


Шифрование и кодирование данных

Результаты криптографических операций редко используются в «сыром» виде. Jsrsasign активно применяет кодирование:

  • HEX — для бинарных представлений
  • Base64 — для передачи через текстовые протоколы
  • PEM — для ключей и сертификатов

Например, AES-шифрование может возвращать Base64-строку:

var enc = KJUR.crypto.Cipher.encrypt("data", "key", "AES");
var base64 = hextob64(enc);

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


Управление ключами и форматы

Jsrsasign поддерживает несколько форматов ключей:

  • PEM (Base64 с заголовками)
  • DER (бинарный формат)
  • PKCS#1 (RSA ключи)
  • PKCS#8 (универсальные приватные ключи)
  • X.509 сертификаты

Работа с ключами осуществляется через KEYUTIL:

var key = KEYUTIL.getKey(pemKey);

Для приватных ключей с паролем используется дополнительный параметр:

var privKey = KEYUTIL.getKey(pemPrivate, "password");

Внутренние механизмы симметричного шифрования

При выполнении AES-операций библиотека последовательно выполняет:

  1. Преобразование входных данных в байтовый массив
  2. Расширение ключа (Key Schedule)
  3. Поблочное шифрование (SubBytes, ShiftRows, MixColumns)
  4. Применение режима (CBC/ECB и др.)
  5. Кодирование результата

Padding чаще всего реализуется по стандарту PKCS#7, где недостающие байты заполняются значением длины добавленных байтов.


Обработка ошибок и ограничения алгоритмов

RSA-шифрование ограничено размером блока:

  • для 1024-bit ключа — около 117 байт данных
  • для 2048-bit — около 245 байт

Попытка зашифровать больший объем данных приводит к ошибке переполнения блока.

Симметричные алгоритмы не имеют таких ограничений, но требуют строгого контроля ключей и IV.


Практика безопасного применения алгоритмов

При использовании криптографических функций Jsrsasign критичны следующие аспекты:

  • использование AES вместо устаревших алгоритмов
  • генерация случайных ключей, а не паролей из строк
  • уникальность IV для каждого шифрования
  • ограничение использования RSA только для ключей
  • применение OAEP-паддинга при RSA при возможности
  • хранение приватных ключей в защищенном виде

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


Работа с потоками и крупными данными

Jsrsasign ориентирован на обработку данных в памяти, поэтому при шифровании больших объемов применяются стратегии разбиения:

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

Это особенно важно при работе в браузерной среде, где ограничены ресурсы памяти и отсутствует полноценный потоковый I/O.


Интеграция алгоритмов в криптографический стек

Шифрование в Jsrsasign редко используется изолированно. Оно обычно является частью более широкого процесса:

  • JWT (JWE/JWS) для токенов
  • CMS для документов
  • TLS-совместимые ключевые структуры
  • PKI-инфраструктура с X.509 сертификатами

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