Comment implémenter l'algorithme SM3 en PHP

PHPz
Libérer: 2023-04-26 13:41:56
original
869 Les gens l'ont consulté

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;
Copier après la connexion

}

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);
Copier après la connexion

}
fonction MG($X, $Y, $Z) {

return ($X & $Y) | ($X & $Z) | ($Y & $Z);
Copier après la connexion

}
fonction P0($X) {

return $X ^ (($X << 9) | ($X >> 23)) ^ (($X << 17) | ($X >> 15));
Copier après la connexion

}
fonction P1($X) {

return $X ^ (($X << 15) | ($X >> 17)) ^ (($X << 23) | ($X >> 9));
Copier après la connexion

}
fonction FF($X, $Y, $Z, $j) {

if ($j >= 0 && $j <= 15) {
    return P0($X ^ $Y ^ $Z);
} else {
    return P1($X ^ $Y ^ $Z);
}
Copier après la connexion

}
fonction GG($X, $Y, $Z, $j) {

if ($j >= 0 && $j <= 15) {
    return P0($X ^ $Y ^ $Z);
} else {
    return P1($X ^ $Y ^ $Z);
}
Copier après la connexion

}
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;
Copier après la connexion

}

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;
Copier après la connexion

}

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal