0
votes

I'm trying to use PHP crypt() to create a basic password hashing/validating scheme. I'm unable to upgrade to PHP 5.5.0 right now, so I can't use password_hash() and password_verify().

My code is as follows:

function myinit_salt()
  {
    $options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';

    for ($i = 0; $i <= 20; $i ++) {
      $options = str_shuffle ( $options );
      $salt .= $options [rand ( 0, 63 )];
    }

    return $salt;
  }

... (encrypting user-provided password upon registration) ...

$salt = myinit_salt();
$blowfish = '$2a$10$';
$enc_pw = crypt($userinput['password'], $blowfish . $salt);

... (store encrypted password in database) ...

... (validating stored password against user-provided password upon login attempt) ...

function verify_password($input_password, $db_password)
  {
    if ($input_password) {
      if (crypt($input_password, $db_password) == $db_password) {
        //authenticated
        return true;
      } else return false;
    } else return false;
  }

This has been returning false even if the user-provided passwords match. So I had verify_password() spit out the values it was using, and this is what was given:

user-provided password ($input_password) = abcxyz123

$db_password = $2a$10$y/WXEmlCb6392Wpf8FMpq.FuwwnaSU51x/xPdFYlTl5y6Bsn51Nzi

verify_password() crypt hash = $2a$10$y/WXEmlCb6392Wpf8FMpq.s8Y6lrJGDMOAJ4d8GffQUEiAWKsEyqS

So it looks like the salt matches, but the password hash doesn't match for some reason.

Can anyone shed some light? Thanks.

2

2 Answers

0
votes

You have two errors in your myinit_salt

function myinit_salt()
  {
    $options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
    $salt = ''; // without it notice would be raised
                     // v
    for ($i = 0; $i <= 21; $i ++) {             // <--- length of salt should be 22
                     // ^ 
      $options = str_shuffle ( $options );
      $salt .= $options [rand ( 0, 63 )];
    }

    return $salt;
  }

http://php.net/manual/en/function.crypt.php

P.S. Why do not use password php extension?

P.S.S. Do not create your own salt generation function. str_shuffle - is not secure for crypt functions. mt_rand too. It's better to use password extension where salt generation already implemented.

0
votes

The generated hash-value in your verify_password() function generates a valid BCrypt hash with the same parameters and the same salt as the stored hash-value. That actually only leaves the alternative, that the inputs are different $userinput['password'] != $input_password.

Anyway it is very likely that you can use the new password_hash() function, and i would recommend to do this. There is a compatibility pack available for PHP version 5.3.7 and later. Even with 5.3 it is possible to use it with a small alteration.