我正在使用this tutorial帮助我在创建帐户时对用户密码进行腌制和哈希处理,然后将这些密码带回来,然后在用户输入密码登录时进行比较。
在这个啧啧中,他们有两个我想要调用的功能。
create_hash()
和
validate_hash()
我随后自己创建了另一个函数,它会对结果进行爆炸,因此我可以从整个函数中删除盐渍字符串。
function explode_hash($password) {
return substr( $password, strrpos( $password, ':' ) + 1);
}
因此,当我在数据库中插入数据时,它看起来像这样
INSERT INTO `users` (`id`, `email`, `passwd`, `passwdhash`)
VALUES
(1,'email@email.com','sha256:1000:mvhkKCAoLgCHb2/Ie0muPIRH0YISriOr:+Ak9g9KV1BPMIRjUorx3/auhU5dgH0lS','+Ak9g9KV1BPMIRjUorx3/auhU5dgH0lS');
请注意,最后一列包含第三列中字符串的最后一部分。
所以最后一步是登录用户将输入他们的电子邮件和密码,我的系统将从数据库中获取哈希值(基于电子邮件)并通过名为
的函数运行它validate_hash()
但结果总是错误的。
有人会花几分钟时间查看这些步骤并尝试了解我无法进行正确比较的原因吗?
答案 0 :(得分:4)
PHP 5.5将自己的函数password_hash()和password_verify()准备好,以简化生成BCrypt哈希值。它们的工作方式与您提出的功能非常相似。我建议使用这个优秀的api,或者它是早期PHP版本的compatibility pack。用法非常简单:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
正如您已经看到的那样,salt包含在生成的哈希值中,可以从那里提取以验证密码。上面的函数将自动从哈希值中提取此信息(盐和成本因子),无需单独存储盐。
答案 1 :(得分:2)
我不知道你的问题究竟是什么,但如果你想爆炸并验证哈希,那就很简单了。
$str = 'sha256:1000:mvhkKCAoLgCHb2/Ie0muPIRH0YISriOr:+Ak9g9KV1BPMIRjUorx3/auhU5dgH0lS'; //str from database
$params = explode(':', $str);
print_r($params);
会打印
Array ( [0] => sha256 [1] => 1000 [2] => mvhkKCAoLgCHb2/Ie0muPIRH0YISriOr [3] => +Ak9g9KV1BPMIRjUorx3/auhU5dgH0lS )
现在你可以检查$ params [1]来获得算法和其他参数以获得正确的值并使用正确的散列函数。
用盐哈希看起来像
hash_function('string_to_be_hashed' + 'unique random salt');
我不知道为什么你的mysql查询中有2个哈希而不是一个哈希。如果你想要散列哈希函数应该返回1个哈希而不是2。
答案 2 :(得分:2)
我快速浏览了您发布的教程。用法应该非常简单。你不应该做任何爆炸或任何事情:
这些功能为你做了所有分裂和爆炸,你不需要关心它。
答案 3 :(得分:-1)
编辑:请勿使用此功能,注释中的说明
我会留下这个答案,因为我已经看过很多这种方法的例子,但是从来没有看到为什么这是错误的方法的解释。感谢ircmaxell指出这个
原帖
我目前使用这些函数来哈希并检查我的密码
function createPassHash($uname, $pass){
$salt = hash('sha256', uniqid(mt_rand(), true) . 'yourPersonalStringHere' . strtolower($uname));
$hash = $salt . $pass;
for ( $i = 0; $i < 100000; $i ++ ) {
$hash = hash('sha256', $hash);
}
$hash = $salt . $hash;
return $hash;
}
function checkPassHash($input, $stored){
$salt = substr($stored, 0, 64);
$hash = $salt . $input;
for ( $i = 0; $i < 100000; $i ++ ) {
$hash = hash('sha256', $hash);
}
$hash = $salt . $hash;
if ( $hash == $stored ) {
return true;
}
else{
return false;
}
}
这通过使用随机数,秘密字符串和用户名一起散列为盐来增加额外的熵程度。还建议盐至少与散列一样长,这也可以确保。