Усі статті

HMAC: чим хеш з ключем відрізняється від звичайного хешу

Звичайна хеш-функція на кшталт SHA-256 дає той самий результат для того самого повідомлення незалежно від того, хто його обчислює. Це добре для перевірки цілісності, але не захищає від підробки: будь-хто може змінити повідомлення й перерахувати новий правильний хеш. HMAC вирішує цю проблему, додаючи до хешування секретний ключ.

Як HMAC поєднує хеш і ключ

HMAC (Hash-based Message Authentication Code) обчислює хеш не лише від повідомлення, а й від секретного ключа, відомого лише відправнику й отримувачу. Обчислити правильний HMAC без знання ключа практично неможливо, тож збіг HMAC підтверджує і цілісність повідомлення, і те, що його створив власник ключа.

Чому це не просто "хеш повідомлення + ключ"

Наївне зчеплення ключа й повідомлення перед хешуванням (наприклад, hash(key + message)) вразливе до атак подовження повідомлення (length extension attack) для деяких хеш-функцій. HMAC використовує спеціальну конструкцію з подвійним хешуванням і внутрішнім/зовнішнім падингом, яка захищена від цього класу атак.

Де застосовується HMAC

HMAC лежить в основі підпису вебхуків (щоб отримувач міг переконатися, що запит прийшов саме від очікуваного сервісу), автентифікації API-запитів, а також є частиною TOTP-алгоритму для генерації одноразових кодів.

Навіщо це потрібно

  • Перевіряти автентичність вебхуків від сторонніх сервісів (наприклад, платіжних систем).
  • Підписувати API-запити без передачі самого секретного ключа по мережі.
  • Розуміти внутрішню механіку TOTP-кодів і токенів сесій.

Порівняння в постійний час

Порівнювати отриманий HMAC з очікуваним звичайним === небезпечно: такий оператор зазвичай зупиняється на першому символі розбіжності, і час виконання порівняння видає зловмиснику, скільки перших символів він вгадав правильно (timing attack). Надійні реалізації використовують функції порівняння за постійний час (наприклад, hash_equals у PHP чи crypto.timingSafeEqual у Node.js), які завжди перевіряють усі байти незалежно від того, де перша розбіжність.

Спробувати інструмент