Php 使用完全相同的输入对密码进行哈希运算不会';t输出相同的值

Php 使用完全相同的输入对密码进行哈希运算不会';t输出相同的值,php,encryption,sha256,Php,Encryption,Sha256,如果你在我的网站上注册的话,我正在尝试对密码进行哈希运算,但是它不起作用。 这是我在注册时哈希密码的代码: $escapedName = mysql_real_escape_string($_POST['user']); $escapedPW = mysql_real_escape_string($_POST['password']); $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); $hashedPW = hash('

如果你在我的网站上注册的话,我正在尝试对密码进行哈希运算,但是它不起作用。 这是我在注册时哈希密码的代码:

$escapedName = mysql_real_escape_string($_POST['user']); 
$escapedPW = mysql_real_escape_string($_POST['password']);

$salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));

$hashedPW = hash('sha256', $escapedPW . $salt);
然后我将其插入数据库(散列密码和salt)。 例如,当我对Sas进行哈希运算时,使用以下盐:
ABAC7AD23185AD19967F0D13E962197962782F00B7EC32D9889C27A93A9E800FA

这是散列密码:
8CA5C5F31FABF382533DBCBFC22B3635D776EC7770C7EAC58D8EF9F1FA3613C

但是,当我尝试在登录时使用完全相同的密码和salt对密码进行哈希处理时,这就变成了哈希传递:
6EB4B16444F18CEE19DB32BD29A39970E3019C5B1972A982AE4CB9A59642DFC

这是我用来登录的代码:

$escapedName = mysql_real_escape_string($_POST['user']);
$escapedPW = mysql_real_escape_string($_POST['password']);
$saltQuery = mysql_query("SELECT salt FROM members WHERE user='{$escapedName}'");
while($result = mysql_fetch_assoc($saltQuery)) {
    $salt = $result['salt'];
}

$hashedPW = hash('sha256', $escapedPW . $salt);

$sql = mysql_query("SELECT * FROM members WHERE user='$escapedName' AND pass='$hashedPW'; ");
while ($res = mysql_fetch_assoc($query2)) {
    $username = $res['user'];
    $PW = $res['pass'];
}

我希望这不是太多的代码,我也希望你能理解我的问题。

无论你在做什么,如果你希望散列是一样的,那是不安全的!有关正确的密码哈希,请参阅

您所需要的一切:

function check_password($password) {  
    ...//get db password to compare
    if (crypt($post_password, $db_results[0]['password']) == $db_results[0]['password']) {  
        return true;  
    } else { return false; }
}

很抱歉,我无法发表评论,但有消息告诉我,您的数据库中的
salt
列有长度限制

示例:salt字段可能只允许64个字符,而生成的salt可能更长,因此在保存salt时,它会被修剪,从而最终更改哈希密码

如果是这样的话,你可能想在保存之前先把盐修剪一下


我建议使用对数据库进行查询。

由于某种原因,对哈希函数的输入必须不同

添加日志输出消息,在两种用例(创建用户和登录)散列之前打印输入。还要确保在日志中的输入周围加引号,以显示空白问题


比较两种情况下散列函数的原始输入和输出,会发现不同之处。如果没有差异,并且散列的输出是相同的,那么查询中就存在一个问题,即在登录案例中查找用户

你取回的盐正确吗?@MathieuImbert我想是的,我已经把代码贴在取回盐的地方了,你觉得怎么样?确保储存的盐的长度与你取回的盐的长度相同。两个密码相同。任何额外的CR/LN都会抛出散列。您是否比较了发送到DB的salt和从DB检索到的salt?手动?显然,如果使用相同的函数callm不能得到相同的输出,那是因为您的输入被破坏了。使用
var\u dump()
并比较字符串。。它们不再得到维护。看到了吗?相反,请了解,并使用或-将帮助您决定使用哪个。我有一个varchar(255)用于存储盐。您能确保一个用户没有多个盐吗?你能更新你的问题的数据库结构吗?你100%确定你保存之前和之后的散列是完全相同的吗?我没有看到任何会导致代码出现问题的内容。在第一个查询中,您在用户名周围使用了括号,但在第二个查询中没有使用括号。此外,我过去对word
user
也有过一些问题,我试图用tildas来逃避它。它不起作用,我也懒得做点什么。我没有真正解决这个问题,而是编写了一个使用sha512的脚本。这方便吗,还是你真的应该用盐?你应该用盐;它不必是64个字符的盐,10个字符就足够了。如果您计划使您的解决方案开源,我建议使用一个名为“secret”的额外salt,该salt被设置为应用程序的配置参数,同时也是一个指定密码应重新散列多少次的参数。