t0berius's avatar

check password against laravel generated password (hash / application key)

Dear community,

I'm using laravel in my main application, where users can register account etc. Now I need to authenticate users input (username and password) on a second server against the userdata I stored on my database server created by laravel. Checking username is easy, but is there an PHP function for bcrypt where I can put my laravel application token into, so I can check, if a password, entered by a user is the same password the user used to register through laravel?

All the best;

0 likes
11 replies
bobbybouwmann's avatar

Well you can't unless you know the application key of the Laravel application.

If you dive into the Laravel code you can see that it's using the BcryptHasher class to check if the password is valid or not. So you need to dive into this code to figure that out ;)

skliche's avatar

@jaheller You can verify the password with the password_verify() function provided by PHP. You need the entered password as well as the password hash as it is stored in the database.

You don't need anything from Laravel to do that.

$passwordIsOk = password_verify( $passwordProvidedByUser, $passwordStoredInDatabase );
3 likes
skliche's avatar

@bobbybouwmann Cool! A bit of a payback as I have already learned quite a few things from your posts as well ;-) Greetings to Apeldoorn!

1 like
t0berius's avatar

@skliche Are you sure this would work? For me it doesn't seems to do so.

<?php
$isOk  = password_verify('testtest', '$10$ceJw/isiH0QnY.Xi5td8h.yeb02B9HMSekCsrDSwSI3/6jLWQ6gH6');
if ($isOk) 
{
    echo "yes";# code...
}
else
    echo "no";
?>

I was sure about laravel uses the application key as salt for generating password hash, am I wrong?

skliche's avatar

@jaheller Yes, definitely, I'm "sharing" bcrypt hashed passwords over multiple applications written in different languages.

The hash you are testing is invalid, it should begin with something like $2y$ (indicating the format used), not with $10$. The latter is the cost parameter that follows the format indicator prefix.

Whatever salt is used to calculate the password hash is stored with the hash in the string that you use. The string consists of the following parts:

  1. format indicator prefix (should be $2y$ for bcrypt)
  2. the cost parameter used to slow down bcrypt, e.g. 10$
  3. 128 bits salt, 22 characters base 64 encoded
  4. 184 bits of the actual password hash calculated by bcrypt, 31 characters base 64 encoded

Example with my username (skliche) as the password:

$2y$10$G1FiMQnvTj09gfDcIb7SueRC9/ADDrEN85OBz03IHGMgDgZYLqTua
  1. format indicator prefix: $2y$
  2. cost parameter: 10$
  3. salt: G1FiMQnvTj09gfDcIb7Sue
  4. password hash: RC9/ADDrEN85OBz03IHGMgDgZYLqTua

So the string in your database contains everything another compliant system needs to know in order to verify a password against the hash.

Try it:

password_verify('skliche', '$2y$10$G1FiMQnvTj09gfDcIb7SueRC9/ADDrEN85OBz03IHGMgDgZYLqTua');

That should work on your system as well.

t0berius's avatar

@skliche

I haven't modified laravel account create method. Should I add "$2y$" in front of my hashed string ?

skliche's avatar

@jaheller Step 1) Let's verify your environment.

Enter the following commands in php artisan tinker:

$password = factory(\App\User::class)->make(['password'=>bcrypt('skliche')])->password;

This command should make a new user with random data and the password skliche. The user is created in memory only, it is not persisted to your database. As a result of that command you should see the password hash. What does it look like? It should include the prefix $2y$.

password_verify('skliche', $password)

This command should verify the password against the hash and return true.

Step 2) Let's verify the data in your database.

The data in the password column in your database should look just like the hash that was output by the first command. It should already include the prefix $2y$. If not, please show us an example of what the data looks like in your users table.

Please or to participate in this conversation.