В практических JavaScript-проектах редко встречается ситуация, когда
весь стек криптографии замыкается на одной библиотеке. Даже при
использовании jsrsasign для формирования и разбора JWE (JSON Web
Encryption) нередко возникает необходимость взаимодействия с более
современными или специализированными реализациями, такими как
jose, Web Crypto API или серверные криптобиблиотеки
Node.js.
Основная сложность совместимости JWE заключается не в самом алгоритме, а в согласованности параметров:
alg)enc)Даже небольшое расхождение в одном из этих элементов приводит к невозможности расшифровки токена между библиотеками.
Библиотека jsrsasign предоставляет достаточно классический API для
работы с JWE через объект KJUR.jwe.JWE. Она ориентирована
на поддержку спецификации JOSE, но при этом сохраняет старый стиль
JavaScript-API.
Пример формирования JWE:
const header = {
alg: "RSA-OAEP",
enc: "A256GCM"
};
const payload = JSON.stringify({
sub: "user123",
role: "admin"
});
const publicKey = `-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----`;
const jwe = KJUR.jwe.JWE.encrypt(payload, publicKey, header);
Данный подход формирует Compact Serialization JWE:
header.encryptedKey.iv.ciphertext.tag
Особенность jsrsasign заключается в том, что он часто используется как «точка совместимости» между устаревшими реализациями JWT и более современными криптобиблиотеками.
Библиотека jose считается одной из наиболее актуальных
реализаций JOSE-стека в JavaScript. При взаимодействии с jsrsasign чаще
всего возникает задача миграции или параллельной работы двух систем.
Типичный сценарий: генерация JWE в jsrsasign и расшифровка в
jose.
Пример расшифровки через jose:
import { compactDecrypt } from "jose";
const privateKey = await importPKCS8(pemPrivateKey, "RSA-OAEP");
const { plaintext } = await compactDecrypt(jweToken, privateKey);
console.log(new TextDecoder().decode(plaintext));
Критически важные условия совместимости:
RSA-OAEP или
RSA-OAEP-256, а не RSAES-PKCS1-v1_5enc должен совпадать (A256GCM,
A128CBC-HS256)Обратная совместимость (jose → jsrsasign) часто работает хуже из-за различий в сериализации protected header.
Web Crypto API используется в браузерных окружениях и современных runtime-средах. Основная проблема интеграции с jsrsasign заключается в различии представления ключей.
Web Crypto использует CryptoKey, тогда как jsrsasign
ожидает PEM или внутренние структуры.
Преобразование ключа для совместимости:
const publicKey = await window.crypto.subtle.importKey(
"spki",
spkiBuffer,
{
name: "RSA-OAEP",
hash: "SHA-256"
},
false,
["encrypt"]
);
Далее возникает архитектурный выбор:
В смешанном режиме чаще встречается следующая схема:
Node.js предоставляет низкоуровневый crypto модуль,
который часто используется для ускорения операций шифрования.
В гибридных системах jsrsasign выполняет роль форматтера JWE, а Node crypto — криптографического ядра.
Пример RSA-OAEP шифрования через Node:
import crypto from "crypto";
const encryptedKey = crypto.publicEncrypt(
{
key: publicKeyPem,
oaepHash: "sha256"
},
Buffer.from(cek)
);
Далее результат может быть интегрирован в структуру JWE, сформированную jsrsasign вручную.
Подобный подход используется в системах, где требуется:
Одна из ключевых проблем взаимодействия библиотек — различие в форматах JWE.
Используется в jsrsasign по умолчанию:
BASE64URL(header).
BASE64URL(encryptedKey).
BASE64URL(iv).
BASE64URL(ciphertext).
BASE64URL(tag)
Чаще встречается в jose:
{
"protected": "...",
"encrypted_key": "...",
"iv": "...",
"ciphertext": "...",
"tag": "..."
}
jsrsasign ограниченно поддерживает JSON-формат, поэтому при интеграции с другими библиотеками часто требуется ручная трансформация структуры.
На практике большинство ошибок совместимости возникает не на уровне кода, а на уровне параметров:
RSA1_5 — устаревший, но всё ещё встречаетсяRSA-OAEP — базовый современный вариантRSA-OAEP-256 — рекомендуемый вариантjsrsasign может по умолчанию использовать менее строгие настройки,
тогда как jose требует явного указания SHA-256.
A128GCMA256GCMA128CBC-HS256Ошибка выбора enc приводит к невозможности расшифровки
даже при корректных ключах.
В сложных системах часто применяется архитектурный паттерн разделения криптографических обязанностей:
Пример распределённого сценария:
Даже при совпадении алгоритмов возможны ошибки из-за различий в кодировании:
Расхождения проявляются в:
Типичная ошибка:
Invalid Compact JWE
Причина почти всегда связана с несовпадением base64url представления.
Миграция редко выполняется одномоментно, чаще используется промежуточный слой совместимости:
Ключевой момент миграции — унификация алгоритмов и отказ от нестандартных конфигураций.
В распределённых системах jsrsasign часто встречается на границе:
При этом jose или native crypto используются внутри
микросервисов.
Типовая схема:
Такой подход снижает зависимость от одного криптографического стека и облегчает обновление компонентов без полной переработки системы.