Вопрос

I am having a serious issue with trying to validate my password when logging into my site. I am using php to create a blowfish encrypted password with salt using the code below.

<?php
function cryptPass($p, $rounds = 9) {
$salt = "";
$saltChars = array_merge(range('A','Z'),range('a','z'),range('0','9'));
for($i = 0; $i < 22; $i++){
    $salt .= $saltChars[array_rand($saltChars)];    
}
return crypt($p, sprintf('$2y$%02d$', $rounds) . $salt);
}
?>

This works fine and the crypted password is put into my mysql database. the problem is on login it will not validate. this is the login script.

if(isset($_POST["u"])){
 // CONNECT TO THE DATABASE
 include_once("php_includes/db_connect.php");
 // GATHER THE POSTED DATA INTO LOCAL VARIABLES AND SANITIZE
 $u = mysqli_real_escape_string($db_connect, $_POST['u']);
 include_once("php_includes/hasher.php");
 $p = (cryptPass($_POST['p']));
 // GET USER IP ADDRESS
$ip = preg_replace('#[^0-9.]#', '', getenv('REMOTE_ADDR'));
 // FORM DATA ERROR HANDLING
 if($u == "" || $p == ""){
     echo "login_failed";
    exit();
 } else {
 // END FORM DATA ERROR HANDLING
     $sql = "SELECT id, username, password FROM users WHERE username='$u' AND activated='1' LIMIT 1";
    $query = mysqli_query($db_connect, $sql);
    $row = mysqli_fetch_row($query);
     $db_id = $row[0];
     $db_username = $row[1];
    $db_pass_str = $row[2];
     if($p != $db_pass_str){
         echo "login_failed";
        exit();
     } else {
//goto the users account

should I not be running the cryptPass function on the incoming user data?

Also of note would be that the mysql database password column is set up as VARCHAR(255) so its got plenty of room. At this point the password crypts right, I am just not able to compare it to the one in database properly. This is my first real try with blowfish pieced together from tutorials all over, I wanted to get away from md5 as php.net advises. Any help would be greatly appreciated. Thanks in advance for reading this.

Это было полезно?

Решение

Here's a slightly more in-depth demonstration as what's found on the PHP crypt() man page:

// Only for demonstration, see mcrypt_create_iv() for a better salt:
//   http://php.net/manual/en/function.mcrypt-create-iv.php
$salt = substr(sha1(date('r')), rand(0, 17), 22);
$cost = 10;
$hash = '$2y$' . $cost . '$' . $salt;
$pass = 'mypass';
$notpass = 'notmypass';

$hashed = crypt($pass, "$hash");

echo "
Hash:
$hash

Hashed:
$hashed

Verified: 
" . crypt($pass, $hashed) . "

Not Verified: 
" . crypt($notpass, $hashed);

https://ignite.io/code/51323c3aec221e7b73000000

Which gives (at least this time):

Hash:
$2y$10$a80ded6289240c2e41a5e4

Hashed:
$2y$10$a80ded6289240c2e41a5euUFPvmt.sb6lBwOE.JTAdxQsDWmmM.Me

Verified: 
$2y$10$a80ded6289240c2e41a5euUFPvmt.sb6lBwOE.JTAdxQsDWmmM.Me

Not Verified: 
$2y$10$a80ded6289240c2e41a5euj06Emi8HigWM6BpqVFZ.ZtpA9wK5c8G

Другие советы

To verify the password you need the salt that was used to create the first password hash. This salt is included in the output string of the crypt() function, and crypt can extract this salt from the password hash.

You can see well how it works when you look at the new hash functions from PHP 5.5 password_hash() and password_verify()...

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

...the function that verifies the login password, needs the hash of the first password. It then can extract the salt and the cost factor from this string, to hash the login password with the same parameters.

I can recommend this new functions, there is a compatibility pack for earlier versions.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top