hash_hmac / hash_equals în PHP

Securitate și hash PHP 5.1.2+ (hash_equals: PHP 5.6+)

Calculează o semnătură HMAC: o amprentă care depinde și de o cheie secretă. Dovedește că datele nu au fost modificate.

Sintaxă
hash_hmac(string $algo, string $data, string $key, bool $binary = false): string

Ce face hash_hmac / hash_equals

O amprentă simplă (hash) poate fi recalculată de oricine a modificat datele. HMAC amestecă datele cu o cheie secretă, pe care o știi doar tu (sau doar tu și partenerul tău). Fără cheie, nimeni nu poate produce o semnătură corectă.

Se folosește pentru linkuri semnate (dezabonare, descărcare), webhook-uri de la procesatori de plăți, API-uri și token-uri. Verificarea se face recalculând semnătura și comparând-o cu hash_equals, care durează la fel indiferent unde diferă textele și nu oferă indicii unui atacator.

Parametri

Parametru Descriere
$algo Algoritmul, de obicei "sha256".
$data Datele semnate.
$key Cheia secretă. Păstreaz-o în afara codului public, de exemplu într-o variabilă de mediu.
$binary Opțional. true pentru rezultat binar.

Ce returnează

Semnătura, ca text hexazecimal.

Exemple

Exemplul 1: Semnarea datelor

<?php
$cheie = "cheie-secreta";
$date = "comanda=1024&suma=259.90";

echo hash_hmac("sha256", $date, $cheie);

Rezultat

8dca1d7569b140598f5bef8ca94548c9818af9c419ad8152afc72e442a5439d6

Exemplul 2: Link de dezabonare care nu poate fi falsificat

<?php
$cheie = "cheie-secreta";
$email = "ana@exemplu.ro";

$sig = hash_hmac("sha256", $email, $cheie);
$link = "/dezabonare?" . http_build_query(["email" => $email, "sig" => $sig]);

// la accesarea linkului
$primit = ["email" => $email, "sig" => $sig];
$corect = hash_hmac("sha256", $primit["email"], $cheie);
var_dump(hash_equals($corect, $primit["sig"]));

// cineva schimbă emailul în link
$corect = hash_hmac("sha256", "mihai@exemplu.ro", $cheie);
var_dump(hash_equals($corect, $primit["sig"]));

Rezultat

bool(true)
bool(false)

Greșeli frecvente

  • Compari semnăturile cu == sau ===. Folosește hash_equals($corect, $primit), cu valoarea calculată de tine pe primul loc.
  • Pui cheia secretă direct în cod, într-un depozit Git public. Oricine o vede poate semna date false.

Comenzi înrudite

  • hash: Calculează amprenta unui text cu algoritmul ales: sha256, sha512, sha3-256, xxh3 și multe altele.
  • password_hash: Creează un hash sigur pentru o parolă, gata de salvat în baza de date. Este modul corect de a stoca parole.
  • http_build_query: Transformă un tablou în textul de interogare al unui URL (a=1&b=2), cu toate valorile codate corect.