用于登录密码的 PHP 盐和哈希 SHA256

Posted

技术标签:

【中文标题】用于登录密码的 PHP 盐和哈希 SHA256【英文标题】:PHP salt and hash SHA256 for login password 【发布时间】:2014-01-12 21:09:26 【问题描述】:

我在我的注册脚本中对密码进行了加密,它们存储在数据库中,我必须使用它们登录,所以我想使用未加密的登录。我已经阅读了这里的一些主题,但没有任何帮助。如何将它添加到我的 login.php 中?盐也存储在数据库中。

这是我的 register.php 加密脚本

$hash = hash('sha256', $password1);

function createSalt()

    $text = md5(uniqid(rand(), TRUE));
    return substr($text, 0, 3);


$salt = createSalt();
$password = hash('sha256', $salt . $hash);

这是我的 login.php 和季节

//Create query
$qry="SELECT * FROM member WHERE username='$username' AND password='$password'";
$result=mysql_query($qry);

//Check whether the query was successful or not
if($result) 
    if(mysql_num_rows($result) > 0) 
        //Login Successful
        session_regenerate_id();
        $member = mysql_fetch_assoc($result);
        $_SESSION['SESS_MEMBER_ID'] = $member['id'];
        $_SESSION['SESS_FIRST_NAME'] = $member['username'];
        $_SESSION['SESS_LAST_NAME'] = $member['password'];
        session_write_close();
        header("location: profile.php");
        exit();
    
    else 
        //Login failed
        //error message 
    
else 
    die("Query failed");

【问题讨论】:

您是在 散列,而不是在加密。 差异。 您没有显示用户名/密码是如何从用户输入的,也没有显示您如何在输入密码哈希和存储的密码哈希之间进行比较。实际上,我无法弄清楚您将如何处理当前的查询,因为在我看来,您需要将盐存储到 DB 以用于将输入与散列密码进行比较。在从数据库中检索数据之前,无法知道密码哈希是什么。另外,我不明白您为什么要对密码值进行两次哈希处理。 在您的代码中,您使用随机盐。如果您不再知道盐,您想以后如何比较密码?或者你也储存了盐? -- 另外请不要使用mysql函数,使用mysqlipdo 如果您有兴趣,您应该看看全新的 php >= 5.5 方法,称为 password_hashpassword_verify,而不是使用您自己的算法(参见 php.net/manual/en/function.password-hash.php)。跨度> 您永远无法取回未加密的密码。要检查登录,请重新创建加盐哈希并将其与 $password 字段进行比较以找到匹配项。 【参考方案1】:

这些示例来自 php.net。谢谢你,我也刚刚了解了新的 php 哈希函数。

阅读 php 文档以了解可能性和最佳实践: http://www.php.net/manual/en/function.password-hash.php

保存密码哈希:

$options = [
    'cost' => 11,
];
// Get the password from post
$passwordFromPost = $_POST['password'];

$hash = password_hash($passwordFromPost, PASSWORD_BCRYPT, $options);

// Now insert it (with login or whatever) into your database, use mysqli or pdo!

获取密码哈希:

// Get the password from the database and compare it to a variable (for example post)
$passwordFromPost = $_POST['password'];
$hashedPasswordFromDB = ...;

if (password_verify($passwordFromPost, $hashedPasswordFromDB)) 
    echo 'Password is valid!';
 else 
    echo 'Invalid password.';

【讨论】:

这是什么魔法?在比较之前您不需要对返回的用户密码应用盐吗? 哇。不@DigitalChris,你没有。来自 php 参考:Note that password_hash() returns the algorithm, cost and salt as part of the returned hash. Therefore, all information that's needed to verify the hash is included in it. This allows the verify function to verify the hash without needing separate storage for the salt or algorithm information. 很酷。 我们需要使用 PASSWORD_BCRYPT 常量,如答案所示,而不是 PASSWORD_DEFAULT 以确保将来不会停止使用现有哈希对吗? ...this constant [PASSWORD_DEFAULT] is designed to change over time - php.net/manual/en/function.password-hash.php 否 @Programster,PASSWORD_DEFAULT 将继续正常工作。如果您将保存加密密码的列限制为不能包含它的长度,那么您的数据库查询将停止工作。【参考方案2】:

根据 php.net,Salt 选项自 PHP 7.0.0 起已被弃用,因此您应该使用默认生成的盐,而且要简单得多

存储密码示例:

$hashPassword = password_hash("password", PASSWORD_BCRYPT);

验证密码的示例:

$passwordCorrect = password_verify("password", $hashPassword);

【讨论】:

【参考方案3】:
array hash_algos(void)

echo hash('sha384', 'Message to be hashed'.'salt');

这里是参考http://php.net/manual/en/function.hash.php的链接

【讨论】:

【参考方案4】:

您无法登录,因为您在登录时没有得到正确的 solt 文本。 有两个选项,第一个是定义静态盐,第二个是如果你想创建动态盐而不是你必须将盐存储在与用户关联的某个地方(意味着在数据库中)。 现在,您将用户solt+password_hash 字符串与此连接,您可以在数据库表中使用用户名触发查询。

【讨论】:

【参考方案5】:

我认为@Flo254 将$salt 链接到$password1 并将它们存储到$hashed 变量中。 $hashed 变量进入 INSERT 查询与 $salt

【讨论】:

【参考方案6】:

您不能这样做,因为您无法知道准确时间的盐分。下面是理论上有效的代码(未测试语法)

<?php
$password1 = $_POST['password'];
$salt      = 'hello_1m_@_SaLT';
$hashed    = hash('sha256', $password1 . $salt);
?>

当你插入时:

$qry="INSERT INTO member VALUES('$username', '$hashed')";

对于检索用户:

$qry="SELECT * FROM member WHERE username='$username' AND password='$hashed'";

【讨论】:

你永远不会存储$salt。你的理论是错误的。 @SverriM.Olsen 您总是存储盐 - 只是没有硬编码到代码中。关键是它是随机的并且每个用户都不同。但是,它始终被存储,因为这是验证密码的唯一方法。 @Jon 你误解了我的评论。此答案中的代码从不存储 $salt 变量。看INSERT查询... @SverriM.Olsen 我明白了。我在澄清你的第一句话,因为它可能会被错误地理解,而不知道你指的是用于盐的变量,而不是存储盐本身,这是必需的^^ @Jon 您实际上确实误解了 Sverri 的评论,否则您对他的评论的回复毫无意义。 “你总是存储盐 - 只是没有硬编码到代码中” - 这从来都不是他的重点。

以上是关于用于登录密码的 PHP 盐和哈希 SHA256的主要内容,如果未能解决你的问题,请参考以下文章

解码哈希sha256加密,知盐

在 phpMyAdmin 中使用 SHA256 设置用户密码后访问被拒绝

php登录加密加盐

WebSockets + PHP(棘轮)登录系统

如何在php5.3.0中使用sha256

是否有任何通常被认为值得信赖的 SHA-256 javascript 实现?