Der SM3-Algorithmus ist ein kryptografischer Hash-Funktionsalgorithmus, der 2010 vom China Computer Cryptography Research Center eingeführt wurde. Er gilt als sehr wichtiger Algorithmus für Staatsgeheimnisse. In diesem Artikel stellen wir vor, wie der SM3-Algorithmus in PHP implementiert wird.
1. Einführung in den Algorithmus
Der SM3-Algorithmus ist ein kryptografischer Hash-Funktionsalgorithmus. Eine kryptografische Hash-Funktion ist eine Methode, die Daten beliebiger Größe als Eingabe akzeptiert und in eine Ausgabe fester Länge umwandelt, wobei der Ausgabewert für verschiedene Eingabewerte unterschiedlich ist. Die kryptografische Hash-Funktion weist die folgenden Eigenschaften auf:
1. Feste Länge: Die Ausgabelänge der kryptografischen Hash-Funktion sollte fest sein, normalerweise 128, 160, 192, 224 oder 256 Bit.
2. Irreversibilität: Bei einer Hash-Ausgabe kann ihre Eingabe nicht bestimmt werden, was als Einweg-Hash-Funktion bezeichnet wird.
3. Starker Widerstand: Bei einem gegebenen Hash-Wert ist es unmöglich, eine Eingabe mit demselben Hash-Wert zu finden, während die Änderung nur eines einzelnen oder einer begrenzten Anzahl von Bits in der Eingabe bedeutet, dass eine Ausgabe erzeugt wird, die sich von der ursprünglichen Eingabe unterscheidet.
Der SM3-Algorithmus verwendet die Merkle-Damgard-Struktur, um die Nachricht in Blöcke aufzuteilen und eine iterative Komprimierungsverarbeitung durchzuführen.
Die Algorithmusverarbeitung ist in 4 Teile unterteilt:
1. Auffüllen: Füllen Sie die Nachricht auf, um sicherzustellen, dass ihre Länge ein Vielfaches von 512 Bit ist.
2. Komprimierung: Blöcke in 256-Bit-Nachrichtenauszüge verarbeiten.
3. Iteration: Verarbeiten Sie jeden Nachrichtenblock iterativ, bis alle Blöcke komprimiert sind.
4. Ausgabe: Generieren Sie den endgültigen 256-Bit-Digest.
2. PHP-Implementierung
1. Padding-Funktion in PHP implementieren, um sicherzustellen, dass die Nachrichtenlänge ein Vielfaches von 512 Bit ist.
function padding($msg) {
$length = strlen($msg) * 8; // 消息长度,单位是比特 $k = 448 - (($length + 64) % 512); // 填充长度 if ($k < 0) { $k += 512; } $msg .= hex2bin("80"); // 消息后面添加1 for ($i = 0; $i < $k / 8 - 1; $i++) { $msg .= hex2bin("00"); // 用0填充 } $msg .= pack("N", $length); // 添加消息长度 return $msg;
}
2. Komprimierung
Implementieren Sie die Komprimierungsfunktion in PHP, um den 512-Bit-Nachrichtenblock in einen 256-Bit-Nachrichtenauszug zu verarbeiten.
Funktion CF($X, $Y, $Z) {
return ($X & $Y) | (~$X & $Z);
}
Funktion MG($X, $Y, $Z) {return ($X & $Y) | ($X & $Z) | ($Y & $Z);
return $X ^ (($X << 9) | ($X >> 23)) ^ (($X << 17) | ($X >> 15));
return $X ^ (($X << 15) | ($X >> 17)) ^ (($X << 23) | ($X >> 9));
if ($j >= 0 && $j <= 15) { return P0($X ^ $Y ^ $Z); } else { return P1($X ^ $Y ^ $Z); }
if ($j >= 0 && $j <= 15) { return P0($X ^ $Y ^ $Z); } else { return P1($X ^ $Y ^ $Z); }
$W = array(); $V = $IV; $A = $IV[0]; $B = $IV[1]; $C = $IV[2]; $D = $IV[3]; $E = $IV[4]; $F = $IV[5]; $G = $IV[6]; $H = $IV[7]; for ($i = 0; $i < 16; $i++) { $W[$i] = unpack("N", substr($msg, $i * 4, 4))[1]; } for ($j = 16; $j < 68; $j++) { $W[$j] = GG($W[$j - 16] ^ $W[$j - 9] ^ ($W[$j - 3] << 15) ^ ($W[$j - 13] >> 17), 15) ^ ($W[$j - 6] << 7) ^ $W[$j - 16]; } for ($j = 0; $j < 64; $j++) { $SS1 = ($A << 12) | ($A >> 20); $SS2 = ($SS1 << 7) | ($SS1 >> 25); $TT1 = FF($A, $B, $C, $j) + $D + $SS2 + $W[$j] + (0x79cc4519 >> $j); $SS1 = ($E << 12) | ($E >> 20); $SS2 = ($SS1 << 7) | ($SS1 >> 25); $TT2 = GG($E, $F, $G, $j) + $H + $SS2 + $W[$j] + (0x7a879d8a >> $j); $D = $C; $C = ($B << 9) | ($B >> 23); $B = $A; $A = $TT1; $H = $G; $G = ($F << 19) | ($F >> 13); $F = $E; $E = P0($TT2); } $V[0] = $V[0] ^ $A; $V[1] = $V[1] ^ $B; $V[2] = $V[2] ^ $C; $V[3] = $V[3] ^ $D; $V[4] = $V[4] ^ $E; $V[5] = $V[5] ^ $F; $V[6] = $V[6] ^ $G; $V[7] = $V[7] ^ $H; return $V;
3. Iteration
Implementieren Sie die Iterationsfunktion in PHP, um jeden Nachrichtenblock iterativ zu verarbeiten, bis alle Blöcke komprimiert sind.
Funktion SM3($msg) {
$IV = array( 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e ); $msg = padding($msg); $n = strlen($msg) / 64; for ($i = 0; $i < $n; $i++) { $block = substr($msg, $i * 64, 64); $IV = SM3_compress($block, $IV); } $digest = ""; foreach ($IV as $v) { $digest .= str_pad(dechex($v), 8, "0", STR_PAD_LEFT); } return $digest;
}
4. Algorithmustest
Um zu überprüfen, ob unsere Implementierung korrekt ist, können wir den kryptografischen Hash-Algorithmustest GM/T 0004-2012 verwenden.
require_once "sm3.php";
$input = "abc";
$expected_output = 6D011A7B19A1456";
$output = SM3($input);
var_dump($output = = = $expected_output); // true
Wir können auch andere Nachrichten zum Testen verwenden, um zu überprüfen, ob unsere Implementierung korrekt ist.
Das obige ist der detaillierte Inhalt vonSo implementieren Sie den SM3-Algorithmus in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!