Rechnernetze
Home Nach oben Stichworte

HMAC und die Pseudorandom-Funktion

Zur Authentisierung in verschiedenen Anwendungen wird in TLS HMAC als Hash-Standard verwendet; HMAC wird mit MD5 und SHA-1 spezifiziert, wobei weitere Algorithmen optional sind; MD5 und SHA-1 werden aber im Hand-Shaking-Verfahren verwendet.

Darüber hinaus wird ein Verfahren spezifiziert, um aus einem gegebenen "Geheimnis" zweier Kommunikationspartner systematisch aber nicht reproduzierbar ohne Kenntnis des Geheimnisses Datenblöcke vorgegebener Länge zu generieren. Diese P(PRF) berechnet aus einem Geheimnis, einem Folgewert und einem Funktionswert (identifying label) eine Ausgabe vorgegebener Länge. Um diese Funktion möglichst sicher zu machen, werden zwei Hash-Algorithmen verwendet, wobei die Sicherheit von einem ausreicht. 

Der Algorithmus wird im Standard wie folgt beschrieben:

Als erstes wird eine Datenerweiterungsfunktion P_hahs(secret,data) definiert, welches eine einzelne Hashfunktion zur Erweiterung eines Geheimnisse und einen Anfangswert (seed) in einen beliebig großen Ausgabewert:

P_hash(secret, seed) = 
    HMAC_hash(secret, A(1) + seed) +
    HMAC_hash(secret, A(2) + seed) +
    HMAC_hash(secret, A(3) + seed) + ...

Dabei bedeut + Konkatenation.

A() ist definiert als
    A(0) = seed
    A(i) = HMAC_hash(secret, A(i-1))

P_hash kann so oft wie benötigt iteriert werden, um die benötigte Menge an Daten zu erzeugen. Sollen beispielsweise mit P_SHA-1 64 Bytes Daten erzeugt werden, so würde dieses viermal iteriert werden (durch A(4)), um 80 Bytes Ausgabedaten zu erzeugen. Die restlichen 16 Bytes der letzten Iteration würden verworfen werden, so dass 64 Bytes Ausgabedaten übrig bleiben.

TLS's PRF wird erzeugt, indem das Geheimnis in zwei Hälften aufgeteilt wird und mit der einen Hälfte werden Daten mit P_MD5 erzeugt, und der anderen Hälfte Daten mit P_SHA-1, wobei die Ausgaben beider Expansionsfunktionen danach ge-x-odert werden. 

S1 und S2 sind die beiden Hälften des Geheimnisses, und jede hat die gleiche Länge. S1 wird von der ersten Hälfte des Geheimnisse, S2 von der zweiten genommen. Ihre Länge wird durch Rundung der halben Gesamtlänge des Geheimisses berechnet; ist das ursprüngliche Geheimnis eine ungerade Anzahl von Bytes, so ist das letzte Byte von S1 gleich dem ersten von S2.

L_S = length in bytes of secret;
L_S1 = L_S2 = ceil(L_S / 2);

Das Geheimnis wird wie oben erläutert in zwei Hälften zerlegt (wobei ein Byte beiden angehören könnte), wobei S1 aus den ersten L_S1 Bytes, S2 aus den letzten L_S2 Bytes besteht. 

Das PRF wird dann definiert als das Ergebnis der Mischung der beiden Pseudozufallsströme, die ge-x-odert werden. 

PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed);

Das Label ist ein ASCII-String. Er muss in genau dieser Form übernommen werden, ohne Längenbyte oder angehängte null. Das Label "slithy toves" würde durch Hashen der folgenden Bytes verarbeitet werden:

73 6C 69 74 68 79 20 74 6F 76 65 73

Man beachte: Da MD5 16 Bytes Ausgabe erzeugt und SHA_1 20 Bytes Ausgaben, stimmen die Grenzen der internen Iteration nicht überein. Um eine 80 Byte Ausgabe zu erzeugen, muss P_MD5 bis A(5) iteriert werden, P_SHA-1 jedoch nur bis A(4).