Спецификация JOSE в JavaScript реализуется через библиотеку jose и охватывает три ключевых механизма: подпись (JWS), шифрование (JWE) и обмен ключами. В основе всех операций лежат два принципиально разных подхода к криптографии:
Оба подхода используются в JOSE не изолированно, а как взаимодополняющие части одной системы безопасности.
Симметричное шифрование основано на использовании одного и того же секрета для двух операций:
Это означает, что обе стороны должны заранее знать общий ключ.
Формально:
ciphertext = Encrypt(plaintext, secretKey)
plaintext = Decrypt(ciphertext, secretKey)
В библиотеке jose симметричное шифрование используется в алгоритмах JWE, например:
dir (Direct Encryption)A256GCM (AES-GCM с 256-битным ключом)A128CBC-HS256 (комбинированный режим шифрования и
HMAC)import { CompactEncrypt, compactDecrypt } from 'jose'
const key = new TextEncoder().encode('super-secret-key-32-bytes!!')
const encoded = new TextEncoder().encode('секретные данные')
const jwe = await new CompactEncrypt(encoded)
.setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })
.encrypt(key)
const { plaintext } = await compactDecrypt(jwe, key)
console.log(new TextDecoder().decode(plaintext))
Симметричное шифрование в JOSE применяется когда:
Асимметричная криптография использует пару ключей:
Данные, зашифрованные одним ключом, могут быть расшифрованы только другим.
ciphertext = Encrypt(plaintext, publicKey)
plaintext = Decrypt(ciphertext, privateKey)
В jose асимметричные алгоритмы применяются в двух ключевых задачах:
RSA-OAEPRSA-OAEP-256ECDH-ESECDH-ES+A128KWimport { generateKeyPair, CompactEncrypt, compactDecrypt } from 'jose'
const { publicKey, privateKey } = await generateKeyPair('RSA-OAEP-256')
const message = new TextEncoder().encode('конфиденциальные данные')
const jwe = await new CompactEncrypt(message)
.setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })
.encrypt(publicKey)
const { plaintext } = await compactDecrypt(jwe, privateKey)
console.log(new TextDecoder().decode(plaintext))
JOSE почти никогда не использует только один тип криптографии.
Вместо этого применяется гибридный подход:
Гибрид объединяет:
Хотя JWS не шифрует данные, он использует ту же криптографическую модель.
HS256 (HMAC SHA-256)import { SignJWT, jwtVerify } from 'jose'
const secret = new TextEncoder().encode('shared-secret')
const token = await new SignJWT({ user: 'alice' })
.setProtectedHeader({ alg: 'HS256' })
.sign(secret)
const { payload } = await jwtVerify(token, secret)
RS256ES256import { generateKeyPair, SignJWT, jwtVerify } from 'jose'
const { publicKey, privateKey } = await generateKeyPair('ES256')
const token = await new SignJWT({ role: 'admin' })
.setProtectedHeader({ alg: 'ES256' })
.sign(privateKey)
const { payload } = await jwtVerify(token, publicKey)
JWE в JOSE состоит из пяти частей:
Эта структура позволяет одновременно использовать оба типа криптографии.
Библиотека jose фактически реализует стандартизированный слой безопасности поверх криптографических примитивов Node.js и Web Crypto API, обеспечивая:
Симметричное шифрование отвечает за скорость обработки данных.
Асимметричное шифрование отвечает за безопасное распределение доверия.
JOSE объединяет оба подхода в единую модель, где каждый компонент решает строго определённую задачу, не конкурируя с другими, а дополняя их.