В браузерной среде криптографические операции выполняются через
встроенный интерфейс Web Crypto API, доступный как
window.crypto.subtle. Именно этот слой используется
библиотекой Jose для всех операций подписи, проверки, шифрования и
расшифрования JSON Web Tokens и JSON Web Encryption объектов.
Web Crypto API накладывает ряд архитектурных ограничений, которые напрямую влияют на работу криптографических библиотек:
PromiseCryptoKeyJose учитывает эти ограничения и строит API поверх
crypto.subtle, сохраняя совместимость между Node.js и
браузером.
Библиотека Jose реализует универсальный слой абстракции над криптографическими примитивами. В браузере этот слой автоматически использует Web Crypto API без необходимости ручной настройки.
Ключевые компоненты:
В браузерной среде все операции делегируются
crypto.subtle, включая:
signverifyencryptdecryptimportKeyexportKeygenerateKeyWeb Crypto API предоставляет нативную генерацию ключевых пар. Jose использует её через собственные обёртки.
Пример создания RSA ключевой пары:
const keyPair = await crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["sign", "verify"]
);
В Jose аналогичная операция упрощается:
import { generateKeyPair } from "jose";
const { publicKey, privateKey } = await generateKeyPair("RS256");
Библиотека автоматически выбирает подходящий алгоритм и конфигурацию для Web Crypto API.
JSON Web Key формат является основным способом представления ключей в Jose.
Web Crypto API поддерживает импорт и экспорт ключей в формате JWK:
const key = await crypto.subtle.importKey(
"jwk",
jwkObject,
{
name: "ECDSA",
namedCurve: "P-256"
},
true,
["sign"]
);
Jose упрощает этот процесс:
import { importJWK } from "jose";
const key = await importJWK(jwk, "ES256");
Экспорт ключа:
import { exportJWK } from "jose";
const jwk = await exportJWK(publicKey);
Подпись токена выполняется через JWS. В браузере используется Web
Crypto API через Jose без прямого вызова
crypto.subtle.sign.
Пример создания JWT:
import { SignJWT } from "jose";
const token = await new SignJWT({ role: "admin" })
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("2h")
.sign(secretKey);
Для асимметричных алгоритмов:
import { SignJWT } from "jose";
const token = await new SignJWT({ userId: 123 })
.setProtectedHeader({ alg: "RS256" })
.sign(privateKey);
Под капотом:
crypto.subtle.signПроверка токена также использует Web Crypto API:
import { jwtVerify } from "jose";
const { payload, protectedHeader } = await jwtVerify(token, publicKey);
Алгоритм работы:
crypto.subtle.verifyПри несоответствии подписи операция завершается исключением.
Web Crypto API поддерживает симметричное и асимметричное шифрование, однако сложные схемы реализуются через Jose.
Пример создания зашифрованного JWT:
import { EncryptJWT } from "jose";
const token = await new EncryptJWT({ data: "secret" })
.setProtectedHeader({ alg: "A256KW", enc: "A256GCM" })
.setExpirationTime("1h")
.encrypt(key);
Расшифрование:
import { jwtDecrypt } from "jose";
const { payload } = await jwtDecrypt(token, key);
Внутри используются:
crypto.subtle.encryptОдной из ключевых задач Jose является работа с Base64URL, так как Web
Crypto API оперирует ArrayBuffer, а JWT требует текстового
представления.
Особенности:
+ и /= на отсутствие paddingJose автоматически выполняет преобразования:
Uint8Array ↔︎ Base64URLArrayBuffer ↔︎ stringWeb Crypto API выполняется нативно, часто с использованием аппаратного ускорения. Это делает Jose эффективным даже при большом количестве операций:
Основные факторы производительности:
Web Crypto API позволяет ограниченно хранить ключи:
extractable: false)CryptoKeyПример ограничения экспорта:
const key = await crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
false,
["encrypt", "decrypt"]
);
Jose работает с такими ключами без необходимости их извлечения.
При использовании Jose в браузере учитываются следующие ограничения:
Некоторые алгоритмы доступны не во всех браузерах, например:
Jose использует единый API, абстрагированный от платформы:
crypto modulewindow.crypto.subtleЭто позволяет переносить код без изменений:
import { jwtVerify } from "jose";
Одинаковая функция работает в обеих средах, различие только в backend-реализации криптографии.
Jose в связке с Web Crypto API позволяет выполнять все операции без сторонних криптографических зависимостей и без утечки ключей в JavaScript-уровень.