Start · Sprachen · PHP · Referenz · sodium_compare

sodium_compare

Funktion

Vergleicht zwei Binärstrings, die große Zahlen (Little-Endian) repräsentieren, und gibt -1, 0 oder 1 zurück.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_compare(string $string1, string $string2): int

Beschreibung

sodium_compare vergleicht zwei Binärstrings, die als große vorzeichenlose Ganzzahlen im Little-Endian-Format interpretiert werden. Die Funktion ist besonders nützlich beim sicheren Vergleich kryptografischer Werte wie Nonces, Zähler oder Schlüsselmaterial, bei denen die Gleichheit oder Ordnung zweier Werte festgestellt werden muss.

Im Gegensatz zu einem einfachen Byte-für-Byte-Vergleich (z. B. mit strcmp) berücksichtigt sodium_compare das Little-Endian-Format, sodass das niederwertigste Byte zuerst steht. Das ist das übliche Format für Nonces in libsodium-Funktionen wie sodium_crypto_secretbox.

Die Funktion gibt -1 zurück, wenn $string1 kleiner als $string2 ist, 0 wenn beide gleich sind, und 1 wenn $string1 größer ist. Beide Strings müssen dieselbe Länge haben, da andernfalls eine SodiumException geworfen wird.

Typische Einsatzszenarien sind die Prüfung, ob eine Nonce bereits verwendet wurde (Replay-Schutz), oder die Verwaltung von Nonce-Zählern, die nach jeder Nachricht inkrementiert werden.

Parameter

Name Typ Default Beschreibung
$string1 Pflicht string Der erste Binärstring, der als große vorzeichenlose Zahl im Little-Endian-Format interpretiert wird.
$string2 Pflicht string Der zweite Binärstring, der als große vorzeichenlose Zahl im Little-Endian-Format interpretiert wird. Muss dieselbe Länge wie string1 haben.

Rückgabewert

Typ
int
Beschreibung
Gibt -1 zurück, wenn $string1 kleiner als $string2 ist, 0 wenn beide gleich sind, und 1 wenn $string1 größer als $string2 ist.

Beispiele

Vergleich zweier Nonces zur Replay-Erkennung

<?php
// Zwei Nonces erzeugen
$nonce1 = sodium_hex2bin('0100000000000000000000000000000000000000000000');
$nonce2 = sodium_hex2bin('0200000000000000000000000000000000000000000000');

$result = sodium_compare($nonce1, $nonce2);

if ($result === -1) {
    echo "nonce1 ist kleiner als nonce2 — akzeptabel, kein Replay.";
} elseif ($result === 0) {
    echo "Nonces sind gleich — möglicher Replay-Angriff!";
} else {
    echo "nonce1 ist größer — möglicher Replay-Angriff!";
}
nonce1 ist kleiner als nonce2 — akzeptabel, kein Replay.

Nonce-Zähler inkrementieren und mit vorherigem Wert vergleichen

<?php
// Aktuelle Nonce (24 Bytes, Little-Endian, beginnend bei 1)
$currentNonce = str_repeat("\x00", 24);
$currentNonce[0] = "\x01";

// Nonce inkrementieren
$nextNonce = $currentNonce;
sodium_increment($nextNonce);

$result = sodium_compare($currentNonce, $nextNonce);

if ($result === -1) {
    echo "Nonce korrekt erhöht — bereit zum Senden.";
    // $nextNonce als neue Nonce speichern und verwenden
} else {
    echo "Fehler: Nonce wurde nicht korrekt erhöht.";
}
Nonce korrekt erhöht — bereit zum Senden.

// Wichtig · Fallstricke

Achtung: Beide Strings müssen exakt dieselbe Länge haben. Bei unterschiedlichen Längen wirft sodium_compare eine SodiumException. Überprüfe die Länge der Eingaben im Voraus, z. B. mit strlen.

Little-Endian-Format: sodium_compare interpretiert die Strings als Little-Endian-Zahlen, d. h. das erste Byte ist das niederwertigste. Dies entspricht dem Format, das von sodium_increment und anderen libsodium-Funktionen verwendet wird. Ein einfaches strcmp liefert für solche Werte falsche Ergebnisse.

Kein Constant-Time-Vergleich: Diese Funktion ist nicht für den Vergleich geheimer Schlüssel oder Authentifizierungstags gedacht. Für Timing-sicheren Vergleich geheimer Werte sollte stattdessen sodium_memcmp verwendet werden.