Первая строка фиксирует точные параметры (алгоритм, чтение, размеры входа), поэтому скопированный результат всегда воспроизводим.
HMAC, PBKDF2 и HKDF — ключевое хеширование с нуля
Одним предложением: голый хеш вроде SHA-256 может вычислить любой, поэтому он ничего не доказывает о том, кто отправил сообщение — HMAC подмешивает секретный ключ, так что только владельцы ключа могут создать (или проверить) дайджест; PBKDF2 и HKDF затем переиспользуют ту же механику HMAC, чтобы превращать секреты в ключи: медленно для паролей и быстро для уже случайного материала.
Что такое HMAC (RFC 2104)
Конструкция. HMAC — это два прогона хеша, а не один. Ваш ключ дополняется до размера блока хеша (64 байта для MD5/SHA-1/SHA-256, 128 для SHA-384/512); сообщение хешируется один раз с ключом XOR фиксированный внутренний паттерн, а этот дайджест снова хешируется с ключом XOR фиксированный внешний паттерн. Эта двойная «сэндвич»-конструкция доказуемо стойка, пока базовый хеш — приличная псевдослучайная функция — поэтому HMAC-MD5 всё ещё противостоит практическим атакам коллизией, которые сломали обычный MD5 (хотя его всё равно вывели из употребления, см. ниже).
Ключи. Работает любая длина ключа: короче размера блока используется как есть (но менее 32 байт не одобряется), длиннее сначала хешируется. Та же страница позволяет ввести ключ как текст, hex или Base64, чтобы 64-hex-символьный ключ из продакшена можно было вставить, не приняв его за 64-символьный текстовый пароль. Чтение записывается в строку результата именно по этой причине.
Где вы с ним встречаетесь. Поле HS256 в заголовке JWT — буквально HMAC-SHA-256 по закодированным в base64url частям токена (Декодер JWT на этом сайте вычисляет именно это, когда вы вставляете секрет HS256). Подписи вебхуков (Stripe, GitHub), AWS SigV4, защита записей TLS (старые версии) и родственный OpenSSH umac-64@openssh.com — всё из одного семейства.
Почему не просто hash(message || key)? Расширение длины: каждый хеш семейства MD5/SHA-1/SHA-2 позволяет атакующему, знающему H(secret || msg), вычислить H(secret || msg || padding || anything) без секрета. Разделение HMAC на внутреннюю и внешнюю части убивает этот класс атак. Это самая частая самодельная ошибка в коде подписи API — и причина, по которой HMAC существует.
Что такое PBKDF2 (RFC 8018)
Медленный по замыслу. У пароля, может быть, около 40 бит реальной энтропии; GPU атакующего перебирает миллиарды сырых SHA-256 в секунду. PBKDF2 запускает HMAC(password, salt) снова и снова — iter раз — так что каждая догадка стоит одинаковых iter HMAC и вам, и атакующему. По умолчанию здесь 600 000 итераций с HMAC-SHA-256 — базовая линия из Шпаргалки OWASP по хранению паролей; ползунок идёт до десяти миллионов, потому что рекомендации по безопасности растут по мере ускорения железа.
Соль. Случайная соль для каждого пароля означает, что одинаковые пользователи больше не хешируются одинаково, а предвычисленные таблицы (радужные таблицы) становятся бесполезными. Она не секретна — хранится рядом с хешем, — ей нужно лишь быть уникальной. Норма — 16 случайных байтов.
Известная слабость. PBKDF2 трудоёмок для процессора, но не для памяти: GPU и ASIC распараллеливают его блестяще. Поэтому современный совет — scrypt или Argon2id там, где проектируется хранение парольных хешей (страница Генератора хешей паролей в этом семействе их описывает), а PBKDF2 остаётся правильным ответом для совместимости и настроек FIPS-140.
Что такое HKDF (RFC 5869)
Сначала извлечь, затем расширить. HKDF делает две работы. Extract: сжимает, возможно, неравномерный исходный материал ключа (например, общий секрет Диффи–Хеллмана) вместе с солью в один короткий псевдослучайный ключ PRK = HMAC(salt, IKM). Expand: растягивает PRK до любой длины, до 255 блоков хеша, причём каждый выходной блок сцеплен с предыдущим и помечен полем info. Результат: один секрет безопасно даёт вам ключ шифрования, ключ MAC и IV, все разделённые.
Не для паролей. HKDF предполагает, что его вход уже полностью энтропийный — он делает один HMAC на каждые 32 выходных байта, поэтому человеческий пароль проходит через него практически мгновенно, именно то, чего хочет атакующий. Пропускать пароли через HKDF вместо PBKDF2 — классическая ошибка проектирования; поле info предназначено для меток назначения ("client traffic key", "server iv"), а не для дополнительной энтропии.
Где вы с ним встречаетесь. TLS 1.3 выводит каждый используемый им ключ из секрета рукопожатия через HKDF; WireGuard, Signal, EAP-TLS 1.3 и JSON Web Encryption (как прямой KDF согласования ключей) — всё появляется на одном семейном дереве.
Якорные значения — воспроизведите их на этой странице
Первые две таблицы — тестовые векторы, на которых построены кнопка «Пример» и самопроверка этой страницы (ключ "key", сообщение «The quick brown fox jumps over the lazy dog»; затем случай в стиле RFC с 16-байтовым ключом 0x0b и сообщением «Hi There»). Все они получены независимой нативной реализацией и повторно проверены на этой странице.
HMAC «fox», ключ = key | Дайджест (hex) |
| HMAC-MD5 | 80070713463e7749b90c2dc24911e275 |
| HMAC-SHA-1 | de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 |
| HMAC-SHA-256 | f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 |
| HMAC-SHA-384 | d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237 |
| HMAC-SHA-512 | b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a |
| Якоря KDF | Параметры | Результат (hex, первые байты) |
| PBKDF2-HMAC-SHA-1 | пароль / соль, c=4096, 32 байта | 4b007901b765489abead49d926f721d065a429c12e463f6c4cd79401085b03db |
| PBKDF2-HMAC-SHA-256 | пароль / соль, c=4096, 32 байта | c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a |
| HKDF-SHA-256 (RFC 5869 A.1) | IKM=0x0b×22, соль=00..0c, info=f0..f9, L=42 | 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 |
| HKDF-SHA-256 (RFC 5869 A.2) | IKM=00..4f, соль=60..af, info=b0..ff, L=82 | b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c… |
| HKDF-SHA-256 (RFC 5869 A.3) | IKM=0x0b×22, пустые соль и info, L=42 | 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 |
Частые ошибки
- Путать HMAC с шифрованием. HMAC доказывает целостность и происхождение (при общем секрете); он ничего не скрывает. Любой без ключа всё ещё видит полное сообщение.
- Путать HMAC с подписью. Цифровые подписи — с открытым ключом: один подписывает, любой проверяет. HMAC симметричен: любой проверяющий мог бы и подделать. Для неотказуемости нужны RSA/ECDSA (см. инструмент RSA этого семейства, когда он будет опубликован), а не HMAC.
- Несовпадение чтения ключа. 64-символьная hex-строка, вставленная в поле текстового ключа, становится 64 байтами, а не 32 — и HMAC полностью меняется. Эта страница печатает чтение в строке результата; когда два инструмента расходятся, это первое, что нужно сравнить.
- Слишком мало итераций PBKDF2. 1000 итераций были разумны в 2000 году; сегодня GPU-фермы их проглатывают. Если ваша система всё ещё хранит хеши с 1000 итерациями, спланируйте миграцию с перехешированием при входе.
- HKDF для пароля. Один HMAC на блок вывода означает, что пароль проходит мгновенно — для паролей используйте PBKDF2 (или Argon2id), а HKDF — для секретов с высокой энтропией.
- Переиспользование одного выведенного ключа для всего. Исправление бесплатно: выводите отдельные ключи с разными метками
info. Два ключа из одного IKM с разными метками независимы по замыслу.
Частые вопросы
HMAC-MD5 взломан? Как хеш, стойкий к коллизиям, MD5 мёртв, но стойкость HMAC-MD5 зависит от MD5 как псевдослучайной функции, и практического взлома не известно. Всё равно вывели из употребления — нет причины выбирать его вместо HMAC-SHA-256, кроме совместимости со старым протоколом.
Какой длины должен быть мой ключ HMAC? Как минимум размер выхода хеша (32 байта для SHA-256) и сгенерированный CSPRNG. Ключ короче дайджеста допускается, но каждый бит ниже него напрямую снижает стойкость.
Становится ли PBKDF2 с большим числом итераций «всё безопаснее» бесконечно? Он линейно повышает стоимость для атакующего, но и линейно повышает стоимость входа для вас. Задача — выбрать наибольшее число, которое терпят ваши пользователи — именно это калибруют цифры OWASP.
Почему HKDF ограничен 255 × размер хеша? Цикл расширения: T(i) = HMAC(PRK, T(i-1) || info || i) с однобайтовым счётчиком i — 255 — наибольшее значение счётчика, жёсткое структурное ограничение RFC 5869, а не выбор политики.
В чём разница между PBKDF2 на этой странице и Генератором хешей паролей? Тот же алгоритм, другая работа. Эта страница выводит сырые байты ключа для использования где-то ещё; страница хешей паролей создаёт строки хранимых учётных данных (со встроенной солью и параметрами) и проверяет вставленные кандидаты по ним.