HMAC erklärt
HMAC (Hash-Based Message Authentication Code) ist ein Mechanismus zur Überprüfung sowohl der Integrität als auch der Authentizität einer Nachricht unter Verwendung einer kryptografischen Hashfunktion in Kombination mit einem geheimen Schlüssel. Im Gegensatz zum einfachen Hashing, das jeder berechnen kann, erfordert HMAC die Kenntnis des geheimen Schlüssels, um den Authentifizierungscode zu generieren oder zu überprüfen.
Ein einfacher Hash wie SHA256 sagt Ihnen, dass eine Nachricht nicht geändert wurde, beweist aber nicht, wer sie erstellt hat. Ein Angreifer, der die Nachricht modifiziert, kann den Hash einfach neu berechnen, und der Empfänger hat keine Möglichkeit, die Manipulation zu erkennen. HMAC löst dies, indem es einen geheimen Schlüssel in die Hash-Berechnung einbezieht. Nur jemand mit dem Schlüssel kann einen gültigen HMAC erzeugen, was ihn zur Authentifizierung von Nachrichten zwischen Parteien geeignet macht, die ein Geheimnis teilen.
Wie HMAC funktioniert
HMAC verwendet zwei Durchläufe der Hashfunktion mit dem geheimen Schlüssel. Der Algorithmus ist in RFC 2104 definiert und funktioniert wie folgt:
- Der geheime Schlüssel wird auf die Blockgröße der Hashfunktion aufgefüllt
- Der aufgefüllte Schlüssel wird mit einer inneren Auffüllkonstante (ipad = 0x36 wiederholt) XOR-verknüpft
- Die Nachricht wird an den inneren aufgefüllten Schlüssel angehängt
- Das Ergebnis wird gehasht
- Der aufgefüllte Schlüssel wird mit einer äußeren Auffüllkonstante (opad = 0x5C wiederholt) XOR-verknüpft
- Der Hash aus Schritt 4 wird an den äußeren aufgefüllten Schlüssel angehängt
- Das Ergebnis wird erneut gehasht
HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))
Dieser Doppel-Hash-Ansatz verhindert Längenerweiterungsangriffe und stellt sicher, dass die HMAC-Konstruktion auch dann sicher bleibt, wenn die zugrunde liegende Hashfunktion Schwächen aufweist.
HMAC vs. einfaches Hashing
| Merkmal | Einfacher Hash (SHA256) | HMAC-SHA256 |
|---|---|---|
| Schlüssel erforderlich | Nein | Ja |
| Integritätsprüfung | Ja | Ja |
| Authentifizierung | Nein | Ja |
| Manipulationserkennung | Vollständige Neuberechnung | Erkennung ohne Schlüssel |
| Am besten geeignet für | Datei-Prüfsummen | API-Authentifizierung |
| Längenerweiterung | Anfällig | Beständig |
Häufige Anwendungsfälle
API-Authentifizierung — der Client signiert jede Anfrage mit HMAC unter Verwendung eines gemeinsamen Geheimnisses. Der Server berechnet den HMAC neu und vergleicht ihn. Wenn sie übereinstimmen, ist die Anfrage authentisch.
JWT-Token-Signierung — obwohl JWT typischerweise einfachere HMAC- oder RSA-Signierung verwendet, ist HMAC ein gültiger Algorithmus für JWT (HS256, HS384, HS512).
Webhook-Verifizierung — Dienste wie Stripe, GitHub und Slack signieren Webhook-Payloads mit HMAC, damit Sie überprüfen können, dass sie vom Dienst stammen.
Sitzungstoken — HMAC kann unfälschbare Sitzungstoken generieren, ohne sie in einer Datenbank zu speichern.
Code-Beispiele
PHP
$secret = 'my-secret-key';
$message = 'message-to-authenticate';
// HMAC generieren
$hmac = hash_hmac('sha256', $message, $secret);
echo $hmac;
// HMAC verifizieren
$expected = hash_hmac('sha256', $message, $secret);
if (hash_equals($expected, $providedHmac)) {
echo 'Authentic';
}
Python
import hmac
import hashlib
secret = b'my-secret-key'
message = b'message-to-authenticate'
# HMAC generieren
hmac_value = hmac.new(secret, message, hashlib.sha256).hexdigest()
print(hmac_value)
# HMAC verifizieren (konstantzeit-Vergleich)
expected = hmac.new(secret, message, hashlib.sha256).digest()
received = bytes.fromhex(provided_hmac)
if hmac.compare_digest(expected, received):
print('Authentic')
JavaScript (Node.js)
const crypto = require('crypto');
const secret = 'my-secret-key';
const message = 'message-to-authenticate';
// HMAC generieren
const hmac = crypto.createHmac('sha256', secret)
.update(message)
.digest('hex');
console.log(hmac);
// Verifizieren
const expected = crypto.createHmac('sha256', secret)
.update(message)
.digest();
HMAC-Algorithmen
HMAC kann jede kryptografische Hashfunktion verwenden. Der Algorithmusname kombiniert typischerweise "HMAC" mit dem Hash-Namen.
| Algorithmus | Hash-Funktion | Ausgabegröße |
|---|---|---|
| HMAC-MD5 | MD5 | 128 Bit |
| HMAC-SHA1 | SHA-1 | 160 Bit |
| HMAC-SHA256 | SHA-256 | 256 Bit |
| HMAC-SHA512 | SHA-512 | 512 Bit |
| HMAC-SHA3-256 | SHA3-256 | 256 Bit |
Verwenden Sie HMAC-SHA256 als Standard. HMAC-MD5 und HMAC-SHA1 sind für sicherheitskritische Anwendungen veraltet.
Sicherheitshinweise
Schlüsselgröße — der Schlüssel sollte mindestens so lang sein wie die Hash-Ausgabe. Für HMAC-SHA256 verwenden Sie einen Schlüssel von mindestens 32 Bytes (256 Bit). Längere Schlüssel werden auf die Blockgröße gehasht.
Geheimhaltung des Schlüssels — die Sicherheit von HMAC hängt vollständig davon ab, dass der Schlüssel geheim bleibt. Verwenden Sie ein Schlüsselverwaltungssystem oder Umgebungsvariablen. Härten Sie Schlüssel niemals im Quellcode ein.
Konstantzeit-Vergleich — vergleichen Sie HMAC-Werte immer mit einer Konstantzeit-Vergleichsfunktion wie hash_equals() in PHP oder hmac.compare_digest() in Python. Ein Timing-Angriff könnte sonst das korrekte HMAC Byte für Byte offenlegen.
Replay-Angriffe — HMAC allein verhindert keine Replay-Angriffe. Fügen Sie einen Zeitstempel oder eine Nonce in die signierte Nachricht ein und verifizieren Sie diese auf dem Server.
Online-Tool
Der HMAC Generator auf Help2Code berechnet HMAC-Werte mit Ihrer Wahl an Algorithmus und geheimem Schlüssel. Verwenden Sie es, um HMAC-Implementierungen zu testen oder Testvektoren während der Entwicklung zu generieren.
Fazit
HMAC bietet Nachrichtenauthentifizierung unter Verwendung eines gemeinsamen Geheimnisses und einer kryptografischen Hashfunktion. Es ist essenziell für die API-Sicherheit, Webhook-Verifizierung und jedes Szenario, in dem Sie sowohl die Integrität als auch die Authentizität einer Nachricht überprüfen müssen. Verwenden Sie HMAC-SHA256 mit einem starken geheimen Schlüssel und vergleichen Sie HMAC-Werte immer mit Konstantzeit-Funktionen.