Slovník pojmů

HMAC

HMAC dokládá pravost a integritu zprávy mezi stranami se společným tajemstvím. Nešifruje obsah ani sám nezabrání replay útoku.

Stručná definice

Podpis zprávy pomocí společného tajemství.

Odesílatel a příjemce znají stejné tajemství. Odesílatel z dat stanovených protokolem spočítá HMAC a výsledek odešle v hlavičce. Příjemce z původních dat znovu spočítá očekávanou hodnotu a porovná ji s podpisem. Shoda říká, že data vytvořil držitel stejného tajemství a cestou se nezměnila.

HMAC je message authentication code, ne asymetrický digitální podpis. Každý držitel tajemství umí zprávu vytvořit i ověřit, takže HMAC neposkytuje nezávislý důkaz třetí straně. Nechrání důvěrnost payloadu ani bez timestampu, nonce nebo ID nezastaví replay dříve platné zprávy.

Použití

Kdy aplikace potřebuje ověřit původ zprávy

Hodí se tam, kde dvě strany bezpečně sdílejí tajemství a potřebují ověřit konkrétní požadavek.

  • webhook od platební brány, marketplace nebo dopravce
  • server-to-server HTTP požadavek uvnitř integračního toku
  • podpis callbacku, kde protokol přesně definuje podepisované hlavičky a tělo
  • ověření integrity vnitřního požadavku spolu s HTTPS a autentizací

Praktický příklad

Ověření podpisu webhooku v PHP

Poskytovatel v tomto zjednodušeném příkladu podepisuje řetězec timestamp.rawBody algoritmem HMAC-SHA-256 a výsledek posílá hexadecimálně v hlavičce. Reálný endpoint musí použít přesné hlavičky, oddělovač, encoding i pravidla poskytovatele.

Tajemství přichází z bezpečné konfigurace. Po ověření následuje uložení ID události s unikátním omezením; samotný HMAC nebrání druhému doručení stejné platné zprávy.

$rawBody = $request->getContent();
$timestamp = (string) $request->headers->get('X-Webhook-Timestamp', '');
$providedSignature = (string) $request->headers->get('X-Webhook-Signature', '');

if (!preg_match('/^\d+\z/', $timestamp) || abs(time() - (int) $timestamp) > 300) {
    throw new AccessDeniedHttpException('Neplatný webhook.');
}

// Podoba vstupu musí přesně odpovídat dokumentaci poskytovatele.
$signingInput = $timestamp . '.' . $rawBody;
$expectedSignature = hash_hmac('sha256', $signingInput, $webhookSecret);

if (!hash_equals($expectedSignature, $providedSignature)) {
    throw new AccessDeniedHttpException('Neplatný webhook.');
}

Jak funguje

Od raw požadavku po bezpečné přijetí webhooku

Tvar zprávy a kódování podpisu určuje poskytovatel; bez jeho dokumentace jej nelze bezpečně domýšlet.

  1. Sestavení vstupu Protokol stanoví raw body, timestamp, ID události nebo jejich spojení. Obě strany musí použít stejné bajty a pořadí.
  2. Výpočet podpisu Odesílatel spočítá HMAC z tohoto vstupu a tajemství. Podpis odešle například jako hex nebo Base64 v určené hlavičce.
  3. Převzetí bez změny Příjemce nejprve načte raw body a relevantní hlavičky. JSON nesmí před ověřením znovu serializovat ani normalizovat.
  4. Ověření a čerstvost Vypočte očekávaný HMAC, porovná jej constant-time funkcí a podle kontraktu ověří timestamp, nonce nebo ID události.
  5. Trvalý účinek Až po ověření uloží událost s ochranou proti duplicitě a práci předá do fronty.

Důležité pojmy

Tajemství, data a protokol musí souhlasit.

Bezpečnost nezávisí jen na algoritmu, ale i na podepisovaných datech a správě tajemství.

Shared secret

Tajemství je klíč pro výpočet i ověření HMAC. Není to uživatelské heslo ani veřejný API klíč; patří do bezpečné konfigurace, ne do logu či repozitáře.

Raw payload a canonicalizace

Podpis platí pro přesně určené bajty. I stejné JSON hodnoty mohou mít jiný zápis mezer, pořadí klíčů nebo escapování. Canonicalizaci určuje protokol.

Algoritmus a kódování

HMAC-SHA-256 je častá volba, ale algoritmus i formát podpisu určuje kontrakt. Aplikace nepřijímá algoritmus ani URL klíče z hlavičky.

Constant-time porovnání

Výsledek se neporovnává běžným == ani ===. V PHP hash_equals() omezuje únik podle místa první neshody; očekávaná hodnota je prvním argumentem.

Replay a rotace

Platný podpis lze přehrát. Časové okno, event ID a trvalá deduplikace řeší jiný problém než HMAC. Staré tajemství při rotaci musí mít omezenou platnost.

Vztah k podobným pojmům

HMAC není šifrování ani univerzální přihlášení.

Pojmy se v integračním HTTP toku potkávají, ale poskytují odlišné bezpečnostní vlastnosti.

Webhook
Webhook často používá HMAC pro ověření odesílatele, ale stále potřebuje deduplikaci.
JWT
JWT je formát tokenu s jiným validačním kontextem. Webhookový HMAC není automaticky JWT.
OAuth 2.0
OAuth pracuje s delegovanou autorizací a tokeny. HMAC podpis zprávy ho nenahrazuje.
HTTPS/TLS
TLS chrání přenos; HMAC ověřuje podepsaná data mezi držiteli tajemství. Pro veřejný endpoint je obvykle potřeba obojí.

Výhody a omezení

Jednoduché ověření za cenu sdíleného tajemství.

Přínosy

  • integrita a ověření odesílatele bez vlastního PKI
  • rychlý výpočet nad přesně definovaným vstupem
  • vhodné pro webhooky a server-to-server integrace

Rizika

  • únik shared secretu dovolí vytvářet platné podpisy
  • HMAC nešifruje payload ani neprokazuje konkrétního držitele tajemství
  • neshoda v raw datech, encodingu nebo timestampu způsobí zamítnutí
  • bez replay ochrany může platná zpráva působit opakovaně

Hranice použití

Použít tehdy, když obě strany umí tajemství bezpečně spravovat.

HMAC se hodí pro integrační kontrakt s předem známým poskytovatelem a přesně popsaným podpisem. Příjemce musí bezpečně spravovat secret, rotaci i dohledatelnost odmítnutých požadavků. Podpis doplňuje ochranu transportu a autorizaci následných kroků.

Nevhodný je tam, kde příjemce potřebuje ověřit podpis bez možnosti zprávu sám vytvořit; tehdy se hodí asymetrický podpis s veřejným ověřovacím klíčem. HMAC také není mechanismus pro ukládání hesel, pro něž slouží záměrně pomalé funkce.

Na co myslet

Ověřit nejprve data, pak jejich businessový význam.

Bezpečný podpis je součást příjmového toku, ne jen podmínka v controlleru.

  • algoritmus, signovací vstup a formát podpisu přesně podle dokumentace poskytovatele
  • raw body před JSON dekódováním a porovnání přes hash_equals()
  • secret v bezpečné konfiguraci, rotace a nulové logování hodnot
  • časové okno, event ID a databázová deduplikace pro omezení replay a retry
  • obecná chyba pro nedůvěryhodný požadavek a testy změněného payloadu

Časté otázky

Co HMAC skutečně zaručuje

Šifruje HMAC payload?

Ne. HMAC ověřuje integritu a držitele tajemství. Obsah chrání HTTPS/TLS nebo šifrování.

Stačí porovnat podpis pomocí ===?

Ne. V PHP je vhodná hash_equals(), určená pro porovnání bezpečné vůči timing útokům.

Proč musí endpoint číst raw body?

Podpis se často počítá nad původními bajty. Opětovné zakódování JSONu může změnit jeho výsledný HMAC.

Zastaví HMAC replay útok?

Ne. Platný požadavek lze poslat znovu. Ochranu doplňuje timestamp, nonce nebo trvale uložené event ID.

Je HMAC vhodný pro ukládání hesel?

Ne. Pro hesla slouží adaptivní hashovací funkce; HMAC ověřuje zprávu sdíleným klíčem.

Jak řeším API a integrační hranice

Příjem externích událostí navrhuji s ověřením.

U webhooků a API integrací řeším ověření, retry, timeouty i businessová pravidla.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.