L'algorithme SM3 est un algorithme de fonction de hachage cryptographique lancé par le Centre chinois de recherche sur la cryptographie informatique en 2010. Il est connu comme un algorithme très important dans les secrets nationaux. Dans cet article, nous présenterons comment implémenter l'algorithme SM3 en PHP.
1.Introduction à l'algorithme
L'algorithme SM3 est un algorithme de fonction de hachage cryptographique. Une fonction de hachage cryptographique accepte des données de n'importe quelle taille en entrée et les convertit en une sortie de longueur fixe, et la valeur de sortie est différente pour différentes valeurs d'entrée. La fonction de hachage cryptographique a les caractéristiques suivantes :
1. Longueur fixe : La longueur de sortie de la fonction de hachage cryptographique doit être fixe, généralement 128, 160, 192, 224 ou 256 bits.
2. Irréversibilité : étant donné une sortie de hachage, son entrée ne peut pas être déterminée, ce qu'on appelle une fonction de hachage unidirectionnelle.
3. Forte résistance : étant donné une valeur de hachage, il est impossible de trouver une entrée avec la même valeur de hachage, tandis que modifier un seul ou un nombre limité de bits dans l'entrée signifie produire une sortie différente de l'entrée d'origine.
L'algorithme SM3 utilise la structure Merkle-Damgard pour diviser le message en blocs et effectuer un traitement de compression itératif.
Le traitement de l'algorithme est divisé en 4 parties :
1. Remplissage : remplissez le message pour vous assurer que sa longueur est un multiple de 512 bits.
2. Compression : traitez les blocs en résumés de messages de 256 bits.
3. Itération : traitez chaque bloc de message de manière itérative jusqu'à ce que tous les blocs soient compressés.
4. Sortie : Générez le résumé final de 256 bits.
2. Implémentation PHP
1. Padding
Implémentez la fonction padding en PHP pour vous assurer que la longueur du message est un multiple de 512 bits.
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. Compression
Implémentez la fonction de compression en PHP pour traiter le bloc de message de 512 bits en un résumé de message de 256 bits.
fonction CF($X, $Y, $Z) {
return ($X & $Y) | (~$X & $Z);
}
fonction MG($X, $Y, $Z) {
return ($X & $Y) | ($X & $Z) | ($Y & $Z);
}
fonction P0($X) {
return $X ^ (($X << 9) | ($X >> 23)) ^ (($X << 17) | ($X >> 15));
}
fonction P1($X) {
return $X ^ (($X << 15) | ($X >> 17)) ^ (($X << 23) | ($X >> 9));
}
fonction FF($X, $Y, $Z, $j) {
if ($j >= 0 && $j <= 15) { return P0($X ^ $Y ^ $Z); } else { return P1($X ^ $Y ^ $Z); }
}
fonction GG($X, $Y, $Z, $j) {
if ($j >= 0 && $j <= 15) { return P0($X ^ $Y ^ $Z); } else { return P1($X ^ $Y ^ $Z); }
}
function SM3_compress($msg, $IV) {
$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. Itération
Implémentez la fonction d'itération en PHP pour traiter de manière itérative chaque bloc de message jusqu'à ce que tous les blocs soient compressés.
function 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. Test d'algorithme
Afin de vérifier si notre implémentation est correcte, nous pouvons utiliser le test d'algorithme de hachage cryptographique GM/T 0004-2012.
require_once "sm3.php";
$input = "abc";
$expected_output = "66C7F0FAD8E2DDDB2D0A6EEA2E2ECEB4E83441BEC4C3056BFCDC6F7E9
D9E8B7F5D6A5B9 6D011A7B19A1456";
$output = SM3($input);
var_dump($output = = = $expected_output); // true
?>
Nous pouvons également utiliser d'autres messages pour tester afin de vérifier si notre implémentation est correcte.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!