Короткие секреты и атаки перебором на HMAC

HMAC в экосистеме JSON Web Token часто используется через алгоритмы семейства HS256, HS384 и HS512. В библиотеке Jose это реализовано через JWS (JSON Web Signature), где симметричный секрет выступает основой для подписи и проверки токена.

Ключевая проблема начинается там, где секрет становится предсказуемым. HMAC сам по себе криптографически устойчив, но его безопасность полностью определяется качеством ключа. Если секрет короткий, словарный или повторяющийся, вся схема превращается в задачу перебора.

Типичные слабости секретов:

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

Даже 32-битное пространство ключей сегодня перебирается тривиально при распределённой атаке.


Как устроена проверка HMAC в Jose

При работе с HS256 библиотека Jose вычисляет подпись следующим образом:

  • берётся header и payload JWT
  • они кодируются в base64url
  • вычисляется HMAC по заданному секрету
  • результат сравнивается с подписью токена

Упрощённо процесс проверки выглядит так:

import { jwtVerify } from 'jose';

const secret = new TextEncoder().encode('super-secret-key');

const { payload } = await jwtVerify(token, secret, {
  algorithms: ['HS256']
});

Если секрет слабый, злоумышленник может не атаковать алгоритм, а атаковать сам ключ.


Почему перебор HMAC возможен

HMAC нельзя “взломать” напрямую в криптографическом смысле, но можно подобрать ключ методом перебора.

Реальные сценарии:

  • словарная атака (dictionary attack)
  • перебор по маске (например, company123, service2024)
  • утечки конфигураций и последующая проверка кандидатов
  • распределённый brute force на GPU/кластерных системах

Если секрет имеет низкую энтропию, атакующий просто проверяет множество возможных ключей, вычисляя подпись и сравнивая результат.


Практическая модель угроз

На практике атака на HMAC выглядит не как математическая криптоатака, а как задача перебора кандидатов:

  1. атакующий получает JWT
  2. знает алгоритм (например, HS256)
  3. предполагает пространство возможных секретов
  4. вычисляет HMAC для каждого кандидата
  5. сравнивает подписи

Скорость проверки HMAC настолько высока, что узким местом становится только генерация кандидатов.


Ошибки конфигурации в системах на Jose

В системах, использующих Jose, часто встречаются одинаковые проблемы:

1. Секрет хранится в коде

const secret = 'mysecret';

2. Секрет одинаков в dev и prod окружениях

3. Использование коротких ключей для HS256

HS256 не требует длинного ключа по спецификации, но на практике ключ должен быть не меньше длины хэш-функции (32 байта для SHA-256).

4. Отсутствие ротации ключей

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


Энтропия как главный фактор защиты

Безопасность HMAC определяется не алгоритмом, а энтропией ключа.

Хороший секрет:

  • минимум 32 байта криптографически случайных данных
  • генерируется через crypto.randomBytes
  • не содержит словарных элементов

Пример генерации:

import { randomBytes } from 'crypto';

const secret = randomBytes(32);

В контексте Jose такой ключ существенно усложняет перебор, делая его практически неосуществимым.


Ограничения перебора на практике

Даже при высокой скорости HMAC вычислений, атакующий сталкивается с ограничениями:

  • экспоненциальный рост пространства ключей
  • стоимость распределённых вычислений
  • необходимость проверять каждый кандидат через корректную подпись JWT

При длине ключа 128 бит полный перебор выходит за пределы физически реализуемых вычислений.


Ошибочное ощущение безопасности из-за JWT

Частая ошибка — считать, что JWT сам по себе защищён. На самом деле JWT лишь контейнер, а безопасность зависит от:

  • алгоритма подписи (HS vs RS/ES)
  • качества ключей
  • правильной проверки алгоритма (защита от alg confusion)
  • хранения секретов

В системах на Jose критично фиксировать допустимые алгоритмы:

jwtVerify(token, secret, {
  algorithms: ['HS256']
});

Без этого возможны подмены алгоритма.


Когда HMAC становится слабым звеном

HMAC перестаёт быть надёжным не из-за криптографии, а из-за инженерных ошибок:

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

Практики снижения риска перебора

В реальных системах на базе Jose защита строится на нескольких уровнях:

  • использование длинных случайных ключей
  • хранение секретов в vault-системах
  • регулярная ротация ключей
  • ограничение времени жизни токена (exp)
  • минимизация доверия к HS-алгоритмам в распределённых системах

Дополнительно применяют переход на асимметричные алгоритмы (RS256, ES256), где проблема перебора секрета исчезает как класс.


Роль времени в атаках на HMAC

Перебор всегда ограничен временем. Даже если алгоритм быстрый, пространство ключей растёт быстрее возможностей вычислений.

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

  • время атаки превышает срок жизни системы
  • стоимость атаки становится экономически нецелесообразной
  • вероятность успеха стремится к нулю

В этом смысле безопасность HMAC — это не абсолют, а баланс между энтропией и ресурсами атакующего.