当前位置: 首页 > 知识库问答 >
问题:

使用PHP存储散列和加盐密码时遇到一些问题

赖浩荡
2023-03-14

我用这个教程来帮助我,当用户创建一个帐户时,对他们的密码进行加盐和散列,然后当用户输入密码登录时,将这些密码带回来并进行比较。

在这个图坦卡蒙中,它们有两个我想调用的函数。

create_hash()

validate_hash()

我随后自己创建了另一个函数,它会爆炸结果,因此我可以从整个have中剥离加盐字符串。

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()

但结果总是假的。

有人会花几分钟时间查看这些步骤并尝试理解我无法进行适当比较的原因吗?

共有3个答案

孙胜泫
2023-03-14

我不知道你到底有什么问题,但是如果你想分解和验证hash,这很简单。

$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个。

乐正心水
2023-03-14

我快速浏览了一下你发布的教程。用法应该很简单。你不需要做任何爆炸或其他事情:

  1. 将从用户获得的密码放入create_hash($password),并将该函数的结果存储在数据库中。没有爆炸,没有任何东西
  2. 当用户未登录并向您提供密码时,只需调用validate_password($user_passport,$password_from_database),如果函数返回true,则让用户进入,否则拒绝输入

这些函数为你做所有的分割和分解,你不需要关心这些。

公孙宗清
2023-03-14

PHP 5.5将准备好它自己的函数password_hash()和password_verify(),以简化生成BCrypt哈希。它们的工作方式与您提出的函数非常相似。我建议使用这个出色的api,或者它的早期PHP版本的兼容性包。用法非常简单:

// 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);

正如您已经看到的,盐包含在生成的哈希值中,可以从中提取以验证密码。上面的函数将自动从哈希值中提取此信息(盐和成本因素),无需单独存储盐。

 类似资料:
  • 我模拟存储密码散列,并在登录过程中验证它。 我有一个名为的方法来获取字符串密码,并通过添加盐返回它的哈希值。 我选择一个静态值,在本例中,我选择一个相同的密码值() 但结果是: 为什么这两个值不相同? 我的代码有什么问题?

  • 虽然我理解加盐和散列密码过程背后的神学,但我不太理解方法论。据我所知,这个问题及其相关答案中列出的方法,以及MSDN的这篇文章,都经历了创建不同长度的salt的步骤,以便在散列给定密码的过程中使用。 但是,稍后检查密码怎么样?据我所知,再次创建哈希将导致生成全新的盐,最终导致在尝试登录时验证失败。 我是否错过了盐或盐配方的保存位置?还是我不太了解这个过程?

  • 我想在C#中使用PBKDF2加胡椒和盐来散列密码。我对密码学有点陌生,所以如果我错了,请随时纠正我。 我之所以使用Rfc2898DeriveBytes类,是因为(根据其他Stackoverflow用户的说法)bcrypt和其他哈希算法在C#中不受本机支持和验证,因此可能会造成安全威胁。这篇文章的目的不是开始讨论哪种哈希算法是最好的。 我的目标是:每个密码都会得到一个随机的盐和胡椒,密码会经过一定数

  • 我正在使用以下代码创建哈希密码和salt: 我正在数据库中存储HashedPassword和Salt。 现在我要验证用户登录时的密码: 这不起作用,我得到了一个完全不同的哈希密码,而不是存储在数据库中的密码。据我所知,您应该在用户登录时输入的密码之前预置salt,然后运行相同的哈希密码函数。上面不是等价于那个吗?

  • 问题内容: 我正在开发一个小型的Web应用程序,该应用程序在内部对用户进行身份验证。一旦用户通过身份验证,我的Web应用程序便会将一些信息(例如userID和Person的名称)传递给第三方Web应用程序。第三方开发人员建议我们对值进行哈希处理和加盐处理。 原谅我的无知,但这到底意味着什么? 我正在用Java编写应用程序。因此,我打算做的是使用Apache Commons Digest Utils