Выбор длины ключей и срока действия

Длина криптографических ключей в JOSE напрямую определяется выбранным алгоритмом и уровнем безопасности, который требуется системе. Библиотека jose в JavaScript работает поверх стандартов JWS, JWE и JWK, поэтому корректный выбор параметров ключей и срока действия токенов определяется не самой библиотекой, а криптографической моделью.

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

Симметричные алгоритмы (HMAC) Алгоритмы семейства HS256, HS384, HS512 используют один секрет для подписи и проверки.

  • HS256 — минимально допустимый секрет 256 бит (32 байта)
  • HS384 — 384 бита (48 байт)
  • HS512 — 512 бит (64 байта)

Практически важное правило: длина секрета должна соответствовать выходу хэш-функции. Использование коротких строк (например, паролей) приводит к уязвимости к перебору.

В jose генерация симметричного ключа:

import { generateSecret } from 'jose'

const secret = await generateSecret('HS256')

Секрет при этом формируется как криптографически стойкий ключ, а не строка.


RSA-алгоритмы (RS256, RS384, RS512) RSA опирается на длину модуля ключа.

  • 2048 бит — минимально допустимый уровень для современных систем
  • 3072 бит — рекомендуемый уровень для долгосрочной безопасности
  • 4096 бит — повышенный уровень безопасности с увеличенной вычислительной нагрузкой

В jose:

import { generateKeyPair } from 'jose'

const { publicKey, privateKey } = await generateKeyPair('RS256')

Размер ключа задаётся параметрами генерации или реализацией по умолчанию (обычно 2048 бит).


ECDSA (ES256, ES384, ES512) Алгоритмы на эллиптических кривых используют фиксированные кривые:

  • ES256 — P-256
  • ES384 — P-384
  • ES512 — P-521

Здесь длина ключа не задаётся в битах напрямую, а определяется кривой. Безопасность достигается меньшими ключами при эквивалентной стойкости по сравнению с RSA.


EdDSA (Ed25519) Современный вариант с фиксированным размером ключа.

  • Ed25519 — 256-битная кривая
  • высокая скорость
  • устойчивость к ряду атак, характерных для ECDSA

Генерация ключей в jose и влияние на безопасность

Библиотека jose абстрагирует низкоуровневую криптографию через JWK и KeyLike структуры. Однако выбор алгоритма фактически фиксирует требования к длине ключа.

Пример RSA:

const { publicKey, privateKey } = await generateKeyPair('RS256', {
  modulusLength: 3072
})

Пример ECDSA:

const { publicKey, privateKey } = await generateKeyPair('ES256')

Пример симметричного ключа:

const secret = await generateSecret('HS512')

Ошибки при выборе длины ключей

Критические ошибки возникают в следующих случаях:

  • использование коротких HMAC-секретов (например, 16 байт и менее)
  • применение RSA 1024 бит (устаревший и небезопасный уровень)
  • смешивание алгоритмов с несоответствующими ключами
  • повторное использование одного ключа для разных криптографических целей

Ключ должен соответствовать одному назначению: подпись или шифрование, но не одновременно без явного разделения.


Срок действия токенов и структура временных ограничений

В 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

  • 5–15 минут
  • минимизация ущерба при компрометации
  • требуют refresh-механизма

Refresh token

  • от нескольких дней до месяцев
  • используется для получения новых access 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"
}

Баланс между длиной ключа и сроком жизни токена

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

  • длинный ключ + долгоживущий токен увеличивает окно атаки при компрометации
  • короткий токен снижает значение компрометации ключа
  • слабый ключ не компенсируется даже минимальным временем жизни токена

Практически безопасная модель строится на сочетании:

  • RSA ≥ 2048 или ECDSA P-256 и выше
  • access token ≤ 15 минут
  • refresh token с контролируемой ротацией
  • регулярная смена ключей с использованием kid