在 PHP 中将密码与 crypt() 进行比较

2022-08-30 23:15:02

我需要了解此功能的基础知识。php.net 文档指出,对于河豚算法,:

河豚用盐散列如下:“$2a$”,一个两位数的成本参数“$”,以及来自字母“./0-9A-Za-z”的22个基数64位数字。在 salt 中使用此范围之外的字符将导致 crypt() 返回长度为零的字符串

因此,根据定义,这应该不起作用:

echo crypt('rasmuslerdorf', '$2a$07$usesomadasdsadsadsadasdasdasdsadesillystringforsalt$');

但是,它吐出:

$2a$07$usesomadasdsadsadsadaeMTUHlZEItvtV00u0.kb7qhDlC0Kou9e

crypt() 似乎已经将盐本身的长度削减到 22。有人可以解释一下吗?

这个函数的另一个方面,我无法弄清楚,当他们使用crypt()来比较密码时。http://php.net/manual/en/function.crypt.php(查看示例 #1)。这是否意味着,如果我对所有加密密码使用相同的盐,我必须首先对其进行加密?结婚

$salt = "usesomadasdsadsadsadae";
$salt_crypt = crypt($salt);

if (crypt($user_input, $salt) == $password) {
   // FAIL WONT WORK
}

if (crypt($user_input, $salt_crypt) == $password) {
   // I HAVE TO DO THIS?
}    

感谢您抽出宝贵时间接受采访


答案 1

下面的代码示例可以回答您的问题。

要使用Blowfish生成散列密码,您首先需要生成一个盐,该盐以$ 2a $开头,然后是迭代计数和22个字符的Base64字符串。

$salt = '$2a$07$usesomadasdsadsadsadasdasdasdsadesillystringfors';
$digest = crypt('rasmuslerdorf', $salt);

将整个$digest存储在数据库中,它既有盐又有摘要。

比较密码时,只需执行此操作,

  if (crypt($user_input, $digest) == $digest)

您正在将消化物作为盐重复使用。crypt知道算法标识符中的盐有多长。


答案 2

每个密码的新盐

$password = 'p@ssw0rd';

$salt = uniqid('', true);
$algo = '6'; // CRYPT_SHA512
$rounds = '5042';
$cryptSalt = '$'.$algo.'$rounds='.$rounds.'$'.$salt;

$hashedPassword = crypt($password, $cryptSalt);
// Store complete $hashedPassword in DB

echo "<hr>$password<hr>$algo<hr>$rounds<hr>$cryptSalt<hr>$hashedPassword";

认证

if (crypt($passwordFromPost, $hashedPasswordInDb) == $hashedPasswordInDb) {
    // Authenticated

推荐