gpt4 book ai didi

php - bcrypt 和随机生成的盐

转载 作者:可可西里 更新时间:2023-11-01 13:39:04 28 4
gpt4 key购买 nike

所以我正在试验 bcrypt。我有一个类(如下所示,我从 http://www.firedartstudios.com/articles/read/php-security-how-to-safely-store-your-passwords 得到的),其中有 3 个函数。第一个是生成随机 Salt,第二个是使用第一个生成的 Salt 生成哈希,最后一个是通过将提供的密码与哈希密码进行比较来验证提供的密码。

<?php
/* Bcrypt Example */
class bcrypt {
private $rounds;
public function __construct($rounds = 12) {
if(CRYPT_BLOWFISH != 1) {
throw new Exception("Bcrypt is not supported on this server, please see the following to learn more: http://php.net/crypt");
}
$this->rounds = $rounds;
}

/* Gen Salt */
public function genSalt() {
/* openssl_random_pseudo_bytes(16) Fallback */
$seed = '';
for($i = 0; $i < 16; $i++) {
$seed .= chr(mt_rand(0, 255));
}
/* GenSalt */
$salt = substr(strtr(base64_encode($seed), '+', '.'), 0, 22);
/* Return */
return $salt;
}

/* Gen Hash */
public function genHash($password) {
/* Explain '$2y$' . $this->rounds . '$' */
/* 2a selects bcrypt algorithm */
/* $this->rounds is the workload factor */
/* GenHash */
$hash = crypt($password, '$2y$' . $this->rounds . '$' . $this->genSalt());
/* Return */
return $hash;
}

/* Verify Password */
public function verify($password, $existingHash) {
/* Hash new password with old hash */
$hash = crypt($password, $existingHash);

/* Do Hashs match? */
if($hash === $existingHash) {
return true;
} else {
return false;
}
}
}
/* Next the Usage */
/* Start Instance */
$bcrypt = new bcrypt(12);

/* Two create a Hash you do */
echo 'Bcrypt Password: ' . $bcrypt->genHash('password');

/* Two verify a hash you do */
$HashFromDB = $bcrypt->genHash('password'); /* This is an example you would draw the hash from your db */
echo 'Verify Password: ' . $bcrypt->verify('password', $HashFromDB);
?>

现在,如果我用“密码”生成一个散列,我会得到一个散列密码,它采用随机生成的 Salt。接下来,如果我再次输入“密码”并使用验证功能,我会得到真正的密码匹配的意思。如果我输入错误的密码,我会得到 false。我的问题是这怎么可能?随机生成的盐呢?怎么没效果?

最佳答案

仔细查看您正在处理的值。生成的随机盐将是:

abcdefg...

输入crypt 的内容如下所示:

crypt($password, '$2y$10$abcdefg...')
| | |
| | +- the salt
| +- the cost parameter
+- the algorithm type

结果如下:

$2y$10$abcdefg...123456789...
| | | |
| | | +- the password hash
| | +- the salt
| +- the cost parameter
+- the algorithm type

换句话说,结果散列的第一部分与 crypt 函数的原始输入相同;它包含算法类型和参数、随机盐和哈希结果。

Input:  $password + $2y$10$abcdefg...
Output: $2y$10$abcdefg...123456789...
^^^^^^^^^^^^^^^^^
first part identical

当您确认密码时,您需要再次使用相同的原始盐。只有使用相同的盐,相同的密码才会散列为相同的散列。而且它仍然存在于散列中,其格式可以传递给 crypt 以重复与生成散列时相同的操作。这就是为什么您需要将密码和哈希值都输入验证函数的原因:

crypt($passwordToCheck, '$2y$10$abcdefg...123456789...')

crypt 获取第一个定义的字符数,直到并包括 abcdefg... 并丢弃其余字符(这就是为什么盐需要是固定数字的原因个字符)。因此它等于与以前相同的操作:

crypt($passwordToCheck, '$2y$10$abcdefg...')

并且将生成相同的散列,当且仅当 $passwordToCheck 相同。

关于php - bcrypt 和随机生成的盐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16736119/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com