HMAC – Nachrichten authentifizieren

Ein Hash allein zeigt nur, ob sich eine Nachricht verändert hat – aber jeder kann einen Hash neu berechnen. HMAC (Hash-based Message Authentication Code) kombiniert die Nachricht mit einem geheimen Schlüssel. Nur wer den Schlüssel kennt, kann den Tag erzeugen oder prüfen.

Wozu? API-Webhooks (Stripe, GitHub), JWT-Signaturen, Cookies vor Manipulation schützen, Daten zwischen Microservices vertrauen können – HMAC ist überall, wo Integrität und Authentizität zählen, ein gemeinsames Geheimnis aber okay ist.

Hash vs. HMAC

Hash (SHA-256)
Zeigt nur, dass etwas verändert wurde. Jeder kann ihn neu berechnen.
HMAC
Zeigt, dass die Nachricht von jemandem mit dem geheimen Schlüssel kommt.
Digitale Signatur (RSA / Ed25519)
Wie HMAC, aber asymmetrisch – jeder kann prüfen, nur der Inhaber des privaten Schlüssels kann signieren.
Klassischer Fehler: Beim Vergleich von Tags nie a === b mit normaler String-Gleichheit nutzen – das kann über Timing-Unterschiede angreifbar sein. Stattdessen eine constant-time comparison verwenden.
// HMAC-SHA256 mit Web Crypto API
async function hmac(key: string, message: string) {
  const cryptoKey = await crypto.subtle.importKey(
    "raw",
    new TextEncoder().encode(key),
    { name: "HMAC", hash: "SHA-256" },
    false,
    ["sign"]
  );
  const sig = await crypto.subtle.sign(
    "HMAC",
    cryptoKey,
    new TextEncoder().encode(message)
  );
  return [...new Uint8Array(sig)]
    .map(b => b.toString(16).padStart(2, "0"))
    .join("");
}