Ce face crypto.createHash / createHmac
O funcție hash transformă orice date într-o amprentă de lungime fixă: aceleași date dau mereu aceeași amprentă, iar o schimbare cât de mică dă alta complet diferită. Se folosește pentru a verifica dacă un fișier descărcat este întreg, pentru a detecta modificări sau ca cheie de cache.
createHash(algoritm) creează un obiect căruia îi dai datele cu update() (de mai multe ori, dacă vin pe bucăți) și la final ceri rezultatul cu digest("hex") sau digest("base64"). Pentru date mici, crypto.hash(algoritm, date) face totul într-un singur apel. Algoritmi uzuali: "sha256", "sha512"; "md5" și "sha1" nu mai sunt sigure, folosește-le doar pentru compatibilitate.
createHmac(algoritm, cheie) calculează o amprentă care depinde și de o cheie secretă. Așa verifici că un mesaj vine de la cineva care știe cheia: de exemplu notificările (webhook) de la procesatorii de plăți. Pentru parole nu folosi niciun hash simplu: folosește crypto.scrypt.
Parametri
| Parametru | Descriere |
|---|---|
algoritm |
"sha256", "sha512", "sha3-256" etc. Lista: crypto.getHashes(). |
update(date, [codificare]) |
Adaugă date (șir sau Buffer); se poate apela de mai multe ori. |
digest([codificare]) |
Termină calculul: "hex", "base64" sau, fără argument, un Buffer. |
cheie |
La createHmac: cheia secretă. |
Ce returnează
digest() întoarce amprenta ca șir sau Buffer. Obiectul nu mai poate fi folosit după digest().
Exemple
Exemplul 1: Amprenta unui text
import { createHash, hash } from "node:crypto";
console.log(createHash("sha256").update("Ana are mere").digest("hex"));
console.log(hash("sha256", "Ana are mere"));
console.log(hash("sha256", "Ana are mere."));
console.log(createHash("sha256").update("Iași").digest("base64"));
Rezultat
04c43a6d8236091578fcbebadfab4940a1f2387d3b21468f2eb6e0e01824089e
04c43a6d8236091578fcbebadfab4940a1f2387d3b21468f2eb6e0e01824089e
481656b0fa73b82651a113ec41089519b832cbdd73e1af591178610f2df58e2f
cE7/J7Amair6dYIjAsxf1osXK34A+PuEWO6aWghwK3E=
Exemplul 2: Hash pentru un fișier, pe bucăți
Obiectul hash este și stream de transformare, deci un fișier mare trece prin el fără să fie încărcat tot în memorie.
import { createHash } from "node:crypto";
import { createReadStream, writeFileSync } from "node:fs";
import { pipeline } from "node:stream/promises";
writeFileSync("factura.txt", "Factura 2026-104\nClient: Ana Popescu\nTotal: 1.250 lei\n");
const h = createHash("sha256");
await pipeline(createReadStream("factura.txt"), h);
console.log(h.digest("hex"));
Rezultat
b0ae1ab4ea6813b7f50c3a453cabcb65743308c5c55476ea0920958ecfa37cf8
Exemplul 3: Verificarea unui webhook cu HMAC
Serverul care trimite notificarea calculează semnătura cu cheia comună. Tu o calculezi din nou și compari cu timingSafeEqual, care nu dezvăluie prin durată câte caractere s-au potrivit.
import { createHmac, timingSafeEqual } from "node:crypto";
const cheie = "cheie-secreta-magazin";
const corp = JSON.stringify({ comanda: 1024, stare: "platita", suma: 250 });
const semnaturaPrimita = createHmac("sha256", cheie).update(corp).digest("hex");
function esteValid(corp, semnatura) {
const asteptat = Buffer.from(createHmac("sha256", cheie).update(corp).digest("hex"));
const primit = Buffer.from(semnatura);
return primit.length === asteptat.length && timingSafeEqual(primit, asteptat);
}
console.log(esteValid(corp, semnaturaPrimita));
console.log(esteValid(corp.replace("250", "2500"), semnaturaPrimita));
Rezultat
true
false
Greșeli frecvente
- Salvezi parolele ca
sha256(parola): se sparg ușor cu tabele precalculate și plăci video. Pentru parole foloseștescryptcu sare aleatorie. - Compari semnăturile cu
===: durata comparației poate dezvălui cât din semnătură este corect. Foloseștecrypto.timingSafeEqual. - Apelezi
digest()de două ori pe același obiect: a doua oară primești eroareaERR_CRYPTO_HASH_FINALIZED. Creează un obiect nou pentru fiecare calcul.
Comenzi înrudite
crypto.scrypt (parole): Transformă o parolă într-o cheie greu de spart, cu sare aleatorie: modul corect de a salva parolele cu modulele Node.js.crypto.randomBytes / randomUUID / randomInt: Valori aleatorii sigure pentru criptografie: octeți pentru chei și token-uri, UUID-uri, numere întregi într-un interval.Buffer: Șir de octeți din Node.js: date binare din fișiere, rețea sau criptografie, cu conversii în text, hex și base64.stream.pipeline: Leagă stream-uri în lanț (citire → transformare → scriere), cu tratarea erorilor și închiderea tuturor la final.