【问题标题】:Retrieving salt+hash from DB for validation从数据库中检索盐+哈希以进行验证
【发布时间】:2012-04-27 15:37:57
【问题描述】:

所以我正在学习 PHP 并且正在开发一个登录页面。我已经想出了如何使用 SHA256 来注册新用户以散列 $salt+$password。我知道有较慢的加密方法,例如 bcrypt,但出于学习目的,我只使用 SHA256。我的问题是,在使用它加密之后:

function HashPassword($password) {
  $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); 
  $hash = hash("sha256", $salt . $password); column
  $final = $salt . $hash;
  return $final;
}

使用准备好的语句,从数据库中检索哈希密码以便我可以使用这样的函数对其进行验证的最佳方法是什么?

function ValidatePassword($password, $hash_pass) {

  $salt = substr($hash_pass, 0, 64); 
  $trueHash = substr($hash_pass, 64, 64); 
  $reHash = hash("sha256" , $salt . $password); 

  return $reHash == $trueHash;
}

【问题讨论】:

    标签: php mysql hash salt


    【解决方案1】:

    原则是你不能找回密码;相反,您使用相同的HashPassword 函数来计算密码尝试的哈希值,然后查询数据库以查找匹配记录。


    编辑

    再次查看您的HashPassword 函数,我意识到您不想在其中生成随机盐,而是将$salt 作为参数;您将传入现有数据库记录中的值,或传入随机生成的值,视情况而定。

    【讨论】:

    • 盐呢?我知道人们能够验证使用盐散列的登录。在这种情况下,由于它是随机生成的,我该如何验证......我有点迷茫。
    • @Jukodan:你的盐应该和你的记录一起保存。
    • 我将我的 salt 作为全局类变量(私有)保存在我需要 hash + salt 的包含脚本中。只需获取他们输入的密码,将您的盐添加到其中,将其存储在变量中,从数据库中检索他们已经散列的密码并比较两者。如果他们匹配,那么你就是金子,如果不匹配,那么他们输入了错误的密码
    【解决方案2】:

    你基本上保存了用盐散列的密码,使其无法识别。

    如果您的数据库在某个时候被黑客入侵,黑客将无法直接读取密码。相反,他将不得不重新创建散列值。

    如果您不为每个用户使用不同的(随机)盐,黑客只需创建一个包含所有可能哈希值的表,并将其与您保存的哈希密码进行比较。

    但是,如果每个密码都在密码中添加了不同的盐,那么在散列之前,黑客必须为每个密码创建一个新表,从而大大增加了获取真实密码所需的工作量。人们希望这会使黑客效率低下或成本过高。

    对于想要验证登录凭据的编码人员,您必须遵循以下模式:

    1. 获取保存在数据库中的盐。
    2. 计算连接的hash = salt + password的has值
    3. 比较计算的和保存的hash === savedHash
    4. 如果它们相同,则它是有效密码。如果不是,那就是密码错误。

    【讨论】:

    • 是的,我理解这个概念,感谢您的额外澄清。让我感到困惑的是如何访问我的数据库中的串联哈希。 select from users password where username='$username'?
    • @Jukodan 您可以执行单个查询来检索盐和哈希密码:SELECT hashedPW, salt FROM users WHERE username='$username'。然后在 PHP 中进行比较。重要的一点是为每个用户提供不同的盐,而不是全局盐(对另一个答案的评论听起来就像你对所有用户只有一个“盐”)。
    • 啊!我想多了,主要是因为当我查询数据库并回显结果时,我收到了“resourced ID #2”而不是预期的散列密码。目前我正在使用: $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));为每个用户生成一个随机盐,然后将 hash = salt+password 存储在一列中。
    • 所以我休息了一下,又回来了。但是,我仍然无法从数据库中检索值。它只是返回一个布尔值 true 而不是一个字符串,所以我的函数无法进行比较。这是我正在使用的:$row_result= $db_con->stmt_init(); $sql_query = 'select password from users where username=?'; $row_result->prepare($sql_query); $row_result->bind_param('s',$username); $row_result->execute(); $hash_pass=$row_result->store_result();
    • 然后我跟进:if(ValidatePassword($password, $hash_pass)){ session_register("username"); //creates a session header("location:index.php");}
    猜你喜欢
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 2012-05-03
    • 1970-01-01
    相关资源
    最近更新 更多