Lorsque vous utilisez la fonction Crypt () de PHP pour le cryptage de mot de passe, de nombreux développeurs remarqueront un phénomène étrange: parfois la longueur du résultat de chiffrement est de 13 caractères, parfois 20, 34, ou même plus. Cette incohérence peut facilement faire penser à tort à tort qu'il y a quelque chose qui ne va pas avec le code, ou que le mot de passe est tronqué ou crypté incorrectement. Alors, que se passe-t-il?
La fonction Crypt () de PHP est une interface de chiffrement encapsulée, et la couche sous-jacente dépend de l'algorithme de chiffrement fourni par le système d'exploitation. Le premier paramètre de cette fonction est la chaîne à crypter, et le deuxième paramètre est "Salt". Cette valeur de sel affecte non seulement l'unicité du résultat de chiffrement, mais détermine également quel algorithme de cryptage est utilisé.
echo crypt("mypassword", "salt");
Si vous ne donnez pas de valeurs de sel ou n'utilisez pas de format incorrect, PHP se repliera automatiquement aux anciennes méthodes de chiffrement, telles que l'algorithme traditionnel DES (Standard de cryptage des données), qui se traduira par une sortie très courte, généralement seulement 13 caractères.
La fonction crypt () prend en charge plusieurs algorithmes et différents algorithmes sont déterminés par le préfixe de la valeur de sel. Voici plusieurs formats de valeur de sel commun et leurs algorithmes de chiffrement correspondants:
algorithme | Format de valeur de sel | Longueur du résultat |
---|---|---|
Des | 2 caractères | 13 caractères |
Md5 | 1 $ ... | 34 caractères |
Flowfish | 2A $ $ ... / 2 $ $ ... | 60 caractères |
SHA-256 | 5 $ ... | 43 caractères |
SHA-512 | 6 $ $ ... | 86 caractères |
Donc, si vous ne passez pas explicitement dans une valeur de sel préfixée ou si vous passez une valeur de sel non formatée, PHP est susceptible de revenir à l'utilisation de l'ancien chiffrement DES, qui ne produit que 13 caractères.
Par exemple:
// utiliser SHA-512 cryptage
echo crypt("mypassword", '$6$rounds=5000$usesomesillystring$');
// La sortie est similaire à:$6$rounds=5000$usesomesill...(Longueur totale approximativement86)
Et le code suivant utilise l'algorithme DES par défaut:
echo crypt("mypassword", 'sa');
// La sortie est similaire à:sahGDf/YwKdl6(seulement13Personnages)
Pour éviter ce problème, utilisez toujours des valeurs de sel avec des préfixes explicites, de préférence les sels aléatoires générés, et choisissez des algorithmes plus sûrs tels que Blowfish ( 2 $ $ ) ou SHA-512 ( 6 $ ).
Vous pouvez générer automatiquement des valeurs de sel comme ceci:
function generateSalt($algo = 'sha512') {
switch ($algo) {
case 'blowfish':
return '$2y$10$' . substr(str_replace('+', '.', base64_encode(random_bytes(22))), 0, 22);
case 'sha256':
return '$5$' . bin2hex(random_bytes(6));
case 'sha512':
default:
return '$6$' . bin2hex(random_bytes(6));
}
}
$password = 'mypassword';
$salt = generateSalt('sha512');
$hash = crypt($password, $salt);
echo $hash;
<?php
function hashPassword($password) {
$salt = '$2y$10$' . substr(str_replace('+', '.', base64_encode(random_bytes(22))), 0, 22);
return crypt($password, $salt);
}
$plainPassword = '123456';
$hashed = hashPassword($plainPassword);
// Supposons enregistré dans la base de données
file_put_contents('/var/www/m66.net/passwords.txt', $hashed . PHP_EOL);
// Vérifier le mot de passe
$inputPassword = '123456';
$isValid = crypt($inputPassword, $hashed) === $hashed;
echo $isValid ? 'Mot de passe correct' : 'Mot de passe d'erreur';
?>
Lorsque vous utilisez la fonction crypte () , la raison fondamentale des différentes longueurs du résultat est que le format de la "valeur de sel" détermine l'algorithme de cryptage. Pour assurer la sécurité et la cohérence du chiffrement:
Passe toujours explicitement dans la valeur de sel de format correct ;
Choisissez des algorithmes modernes et sécurisés tels que 2 ans $ ou 6 $ $ ;
Ne comptez pas sur un comportement par défaut ou des formats de sel court .
Après avoir compris ces détails sous-jacents, vous pouvez éviter les risques de sécurité cachés dans le traitement du mot de passe et rendre votre logique de chiffrement plus contrôlable et plus fiable.