Длина криптографических ключей в JOSE напрямую определяется выбранным алгоритмом и уровнем безопасности, который требуется системе. Библиотека jose в JavaScript работает поверх стандартов JWS, JWE и JWK, поэтому корректный выбор параметров ключей и срока действия токенов определяется не самой библиотекой, а криптографической моделью.
В JOSE используются как симметричные, так и асимметричные алгоритмы подписи и шифрования. Каждый класс алгоритмов предъявляет собственные требования к длине ключа.
Симметричные алгоритмы (HMAC) Алгоритмы семейства HS256, HS384, HS512 используют один секрет для подписи и проверки.
Практически важное правило: длина секрета должна соответствовать выходу хэш-функции. Использование коротких строк (например, паролей) приводит к уязвимости к перебору.
В jose генерация симметричного ключа:
import { generateSecret } from 'jose'
const secret = await generateSecret('HS256')
Секрет при этом формируется как криптографически стойкий ключ, а не строка.
RSA-алгоритмы (RS256, RS384, RS512) RSA опирается на длину модуля ключа.
В jose:
import { generateKeyPair } from 'jose'
const { publicKey, privateKey } = await generateKeyPair('RS256')
Размер ключа задаётся параметрами генерации или реализацией по умолчанию (обычно 2048 бит).
ECDSA (ES256, ES384, ES512) Алгоритмы на эллиптических кривых используют фиксированные кривые:
Здесь длина ключа не задаётся в битах напрямую, а определяется кривой. Безопасность достигается меньшими ключами при эквивалентной стойкости по сравнению с RSA.
EdDSA (Ed25519) Современный вариант с фиксированным размером ключа.
Библиотека jose абстрагирует низкоуровневую криптографию через JWK и KeyLike структуры. Однако выбор алгоритма фактически фиксирует требования к длине ключа.
Пример RSA:
const { publicKey, privateKey } = await generateKeyPair('RS256', {
modulusLength: 3072
})
Пример ECDSA:
const { publicKey, privateKey } = await generateKeyPair('ES256')
Пример симметричного ключа:
const secret = await generateSecret('HS512')
Критические ошибки возникают в следующих случаях:
Ключ должен соответствовать одному назначению: подпись или шифрование, но не одновременно без явного разделения.
В JOSE срок действия задаётся через стандартные JWT-claims:
exp — время истеченияiat — время выпускаnbf — время, с которого токен становится валиднымПроверка срока действия не является частью криптографии, но критически влияет на безопасность системы.
Типичная структура:
import { SignJWT } from 'jose'
const token = await new SignJWT({ role: 'user' })
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('15m')
.sign(secret)
Длительность зависит от типа токена и модели угроз.
Короткоживущие access token
Refresh token
Комбинация короткого access token и долгоживущего refresh token снижает риск повторного использования украденных токенов.
При проверке exp и nbf учитывается
возможный сдвиг времени между системами.
В jose:
import { jwtVerify } from 'jose'
const { payload } = await jwtVerify(token, secret, {
clockTolerance: 10
})
Clock tolerance компенсирует рассинхронизацию серверных часов.
Короткий срок жизни токенов уменьшает зависимость от частой ротации ключей. Однако в крупных системах применяется стратегия:
kidПример заголовка:
{
"alg": "RS256",
"kid": "key-2026-01"
}
Безопасность системы определяется не только криптографической стойкостью ключа, но и временем его потенциального использования злоумышленником.
Практически безопасная модель строится на сочетании:
kid