PHP:哈希代码不再工作


PHP: Hashing code not working any longer?

我用了这个散列函数一段时间(从互联网上得到的(。问题是,它过去可以立即工作,但现在却在抱怨一个参数。以下是代码:

function generateHash($plainText, $salt = null)
{
    if ($salt === null)
    {
        $salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }
    return $salt . sha1($salt . $plainText);
}

所以我会在方法调用中使用以下代码:

validateUserInput($userid, $pass);

validateUserInput为:

function validateUserInput($username, $password)
{
    //$username = mysql_real_escape_string($username);
    //$password = mysql_real_escape_string($password);
    if(!$username || !$password)
    {
        //$errors['credentials'] = 'Missing Credentials!';
        //$_SESSION['errors_array'] = $errors;
        //echo $errors['credentials'];
        header("LOCATION:XXXXXXX.php");
    }
    $local_salt = generateHash($password);
    //echo $local_salt;
    $groupid;
    if($username != null && $password !=null)
    {   
        connectToServer();
        $result = mysql_query("SELECT * FROM users WHERE hashkey = '{$local_salt}'");
        while($row_access = mysql_fetch_array($result))
        {
            $groupid = $row_access['groupid'];
        }
        if(!isset($result))
        {
            $errors['not_found_user'] = 'No Users Found with Provided Credentials!';
            //$_SESSION['errors_array'] = $errors;
            $userfound = 0;
            $_SESSION['user_available'] = $userfound;
        }elseif(isset($result)){
            $_SESSION['user_logged'] = array('username' => $username, 'password' => $password, 'salt' => $local_salt, 'groupid' => $groupid);
            $userfound = 1;
            //echo "stored";
            $_SESSION['user_available'] = $userfound;
        }       
    }
}

最后的错误是:

Warning: substr() expects parameter 3 to be long, string given in /home/XXXX.php on line 64

这指向函数generateHash()

错误本身告诉了一切。常数SALT_LENGTH不是long。我怀疑它根本没有定义,所以PHP将空字符串转换为字符串("SALT_LENGTH"(,并将传递给substr(),这会引起抱怨。

话虽如此。。。这个代码是危险的错误:

  1. if(!isset($result)):真的吗?此条件将始终为false,因为$result将始终被设置(除非您遇到mysql_query()的问题,但这并不能告诉您登录的有效性(。由于mysql_query()从不返回null,因此不会拒绝任何登录

  2. 此查询:

    SELECT * FROM users WHERE hashkey = '{$local_salt}'
    

    无效。CCD_ 11。在generateHash函数中,如果没有给定salt,则会为您随机创建一个salt。因此,对generateHash的每次调用都会生成一个新的散列,这意味着它不能与数据库中的任何东西进行比较。

基于上面两个(非常(严重的错误,我将永远放弃这段代码。


当使用盐时,检查有效哈希的正确方法是:

$_SESSION['user_logged'] = null;
// fetch hashed pw from db, where username is the submitted username
$result = mysqli_query("SELECT hash FROM users WHERE username = '{$username}'");
if ($result->num_rows != 0) 
{
     $row = $result->fetch_assoc();    
     $hash = $row['hash'];
     $salt = substr($hash, 0, SALT_LENGTH); // extract salt 
     if (generateHash($password, $salt) == $hash) 
     {
         // login successful. 
         $_SESSION['user_logged'] = $username; // don't store passwords here
     }
}
// if $_SESSION['user_logged'] is not set, the login failed
if (!isset($_SESSION['user_logged'])) 
{
    // you *don't* want to tell people which one (login or pw) is invalid
    echo 'Invalid login or password';
}

注意:非常重要的是,SALT_LENGTH最多为32,否则由于generateHash()的实现方式,这将不起作用。

显然SALT_LENGTH不是整数。找到它的定义并更正它。

与其每次编写应用程序时都创建一个新的哈希函数,不如使用php:crypt((提供的函数(我建议使用任何blowfish或sha256+哈希(。

当从数据库中选择信息时,您应该按用户名进行选择,然后使用php检查哈希是否符合密码。