Start · Sprachen · PHP · Referenz · hash_hkdf

hash_hkdf

Funktion

Leitet aus einem Eingabeschlüssel mittels HKDF (HMAC-based Key Derivation Function, RFC 5869) einen kryptografisch sicheren Schlüssel ab.

seit PHP 7.1.2 Kategorie: crypto

Signatur

hash_hkdf(string $algo, string $key, int $length = 0, string $info = '', string $salt = ''): string

Beschreibung

hash_hkdf() implementiert die HKDF-Schlüsselableitungsfunktion gemäß RFC 5869. Sie ermöglicht es, aus einem vorhandenen Schlüsselmaterial (z. B. einem gemeinsamen Geheimnis aus einem Diffie-Hellman-Austausch) einen oder mehrere kryptografisch starke Schlüssel für verschiedene Verwendungszwecke abzuleiten.

HKDF besteht intern aus zwei Schritten: Extract (Normalisierung des Eingabematerials mit einem optionalen Salt) und Expand (Ableitung des gewünschten Ausgabeschlüssels mit einem optionalen Kontextparameter info). Durch den info-Parameter lassen sich aus demselben Schlüsselmaterial isolierte Schlüssel für unterschiedliche Zwecke (z. B. Verschlüsselung vs. Authentifizierung) erzeugen.

Typische Anwendungsfälle sind: Ableitung von Sitzungsschlüsseln aus einem Master-Secret, Erstellung domänenspezifischer Schlüssel aus einem gemeinsamen Geheimnis sowie die Schlüsselexpansion in Protokollen wie TLS oder Signal.

Der Rückgabewert ist eine rohe Binärzeichenkette. Soll der Schlüssel textlich dargestellt werden, kann er anschließend mit bin2hex() oder base64_encode() kodiert werden.

Parameter

Name Typ Default Beschreibung
$algo Pflicht string Name des zu verwendenden Hash-Algorithmus (z. B. 'sha256', 'sha512'). Muss ein von hash_algos() unterstützter, nicht-XOF-Algorithmus sein.
$key Pflicht string Das Eingabeschlüsselmaterial (IKM). Darf nicht leer sein. Dies ist das Rohmaterial, aus dem der neue Schlüssel abgeleitet wird.
$length int 0 Gewünschte Länge des abgeleiteten Schlüssels in Bytes. Bei 0 wird die native Ausgabelänge des gewählten Hash-Algorithmus verwendet. Der Maximalwert beträgt 255-mal die Hash-Ausgabelänge.
$info string Optionaler kontextspezifischer Informationsstring (z. B. 'encryption' oder 'authentication'). Ermöglicht die Ableitung verschiedener Schlüssel aus demselben Eingabematerial für unterschiedliche Zwecke.
$salt string Optionaler Salt-Wert für den Extract-Schritt. Wird empfohlen, wenn das Eingabeschlüsselmaterial nicht bereits gleichmäßig verteilt ist. Bei leerem String wird ein nullbytebasierter Standard-Salt verwendet.

Rückgabewert

Typ
string
Beschreibung
Gibt eine rohe Binärzeichenkette mit dem abgeleiteten Schlüssel der angeforderten Länge zurück. Im Fehlerfall (ungültiger Algorithmus, leerer Schlüssel, zu große Länge) wird eine ValueError-Exception geworfen (seit PHP 8.0; davor false).

Beispiele

Einfache Schlüsselableitung mit SHA-256

<?php
// Gemeinsames Geheimnis (z. B. aus DH-Austausch)
$sharedSecret = random_bytes(32);

// Schlüssel für Verschlüsselung ableiten
$encryptionKey = hash_hkdf('sha256', $sharedSecret, 32, 'encryption', 'mein-salt');

// Schlüssel für Authentifizierung ableiten (gleicher Input, anderes info)
$authKey = hash_hkdf('sha256', $sharedSecret, 32, 'authentication', 'mein-salt');

echo 'Verschlüsselungsschlüssel: ' . bin2hex($encryptionKey) . PHP_EOL;
echo 'Authentifizierungsschlüssel: ' . bin2hex($authKey) . PHP_EOL;
echo 'Schlüssel sind identisch: ' . ($encryptionKey === $authKey ? 'ja' : 'nein') . PHP_EOL;
Verschlüsselungsschlüssel: (64 hexadezimale Zeichen) Authentifizierungsschlüssel: (64 hexadezimale Zeichen) Schlüssel sind identisch: nein

Schlüsselableitung mit benutzerdefinierter Länge und SHA-512

<?php
// Master-Secret aus Passwort und Salt erzeugen (z. B. via password_hash wäre hier falsch,
// deshalb verwenden wir hash_pbkdf2 als IKM-Quelle)
$masterSecret = hash_pbkdf2('sha512', 'geheimes-passwort', 'anwendungs-salt', 100000, 64, true);

// 16-Byte AES-128-Schlüssel ableiten
$aesKey = hash_hkdf('sha512', $masterSecret, 16, 'aes-128-cbc key', 'session-123');

// 16-Byte IV ableiten
$iv = hash_hkdf('sha512', $masterSecret, 16, 'aes-128-cbc iv', 'session-123');

echo 'AES-Schlüssel (hex): ' . bin2hex($aesKey) . PHP_EOL;
echo 'IV (hex): ' . bin2hex($iv) . PHP_EOL;
echo 'Schlüssellänge: ' . strlen($aesKey) . ' Bytes' . PHP_EOL;
AES-Schlüssel (hex): (32 hexadezimale Zeichen) IV (hex): (32 hexadezimale Zeichen) Schlüssellänge: 16 Bytes

// Wichtig · Fallstricke

Sicherheitshinweise:

  • hash_hkdf() ist kein Passwort-Hashing. Für Passwörter muss password_hash() verwendet werden. HKDF ist für bereits starkes Schlüsselmaterial gedacht.
  • Der info-Parameter ist entscheidend für die Schlüsseltrennung: Verschiedene Anwendungskontexte sollten stets unterschiedliche info-Werte verwenden, um Schlüssel sicher voneinander zu isolieren.
  • Der Salt ist optional, aber empfohlen, wenn das Eingabematerial möglicherweise nicht gleichmäßig verteilt ist (z. B. direkt aus einem DH-Austausch).
  • Ab PHP 8.0 wirft die Funktion bei ungültigen Parametern (leerer Schlüssel, unbekannter Algorithmus, zu große Länge) eine ValueError-Exception. In PHP 7.x wurde false zurückgegeben — Fehlerbehandlung ist daher versionsabhängig zu gestalten.
  • XOF-Algorithmen wie shake128 oder shake256 werden nicht unterstützt und führen zu einem Fehler.