开发者

PHP: Hashing code not working any longer?

I used this hash function for a while (got it from the internet). The thing is it used to work immediately but now it is complaining about a paramter. The following is the code:

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

So I would use this code in the method call:

validateUserInput($userid, $pass);

and validateUserInput is:

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;
        }       
    }
}

finally the error is:

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

This is pointing to the function generateHash()


The error itself tells you everything. The constant SALT_LENGTH is not a long. I suspect it's not defined at all, so PHP converts the bare string to a string ("SALT_LENGTH") and passes that to substr(), which complains.

That being said... This code is dangerously wrong:

  1. if(!isset($result)): Really? This condition will always be false because $result will always be set (unless you run into a problem with mysql_query(), but that doesn't tell you anything about the valididty of the login). And since mysql_query() never returns null, no logins will ever be rejected.

  2. This query:

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

    Is invalid. $local_salt = generateHash($password);. From the generateHash function, if a salt is not given, one will be randomly created for you. Thus, every call to generateHash will generate a new hash, which means it can't be compared to anything in the database.

On the basis of the two (very) egregious mistakes above, I would throw away this piece of code for good.


The correct way to check for a valid hash when a salt is used is something like:

$_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';
}

Note: It's very important that the SALT_LENGTH is at most 32, or this won't work because of the way generateHash() is implemented.


Clearly SALT_LENGTH is not an integer. Find where it's defined and correct this.


Instead of making a new hashing function each time you write an application , you should utilize the one provided to you by php: crypt() ( i would recommend to go with any blowfish or sha256+ hash ).

And when selecting information from database, you should select it by username and then, with php, check if hash fits the password.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜