PHP password_verify () vs Python bcrypt.hashpw ()

So, right on him.

I have a [simple] PHP REST API where I get a hashed password using the X-API-KEY header key. This works great when interacting with another PHP script, and the phrase is hashed using the PHP password_hash () method. However, when I try to interact with the API through Python and the Requests library, the key is rejected. Here are some examples:

PHP:

<?php $usrid = '123456'; $dt = new DateTime(); $secret = "secret{$usrid}{$dt->format('Ymd')}"; $hashed = password_hash($secret, PASSWORD_BCRYPT); echo $secret."\n"; echo $hashed."\n"; echo(phpversion()); ?> 

Python:

 #!/usr/bin/python import bcrypt, datetime, sys usrid = '123456' # user id t = datetime.datetime.now().strftime('%Y%m%d') secret = "secret{usrid}{t}".format(usrid=usrid,t=t) hashed = bcrypt.hashpw(secret, bcrypt.gensalt()) print secret print hashed print '%d.%d.%d' % (sys.version_info[:3]) 

The output of each of them is as follows:

 PHP: secret12345620161116 $2y$10$/WUBS2RkTlfcgPxvmqYRI.EkBD/CPgnpE9rYvOqweERgSwFeENUDO 5.6.24 Python: secret12345620161116 $2b$11$9v/l6KglHiNgOybw1Y8jWeCFHiAfv.cguO1Qmc7Noe4azSluoBeHO 2.7.11 

Now, obviously, they are different, this is the point, but when you pass the Python output to the PHP password_verify () function, it returns False. PHP result is well tested.

There must be something that I am missing here, but, for the life of me, I cannot find it. I tried using different salt options without success. What am I missing? Are these two simply incompatible? It seems silly if it's true.

Thank you for the advanced, smart internet people.

UPDATE

[I updated the scripts with the following two lines for tests]

 PHP: $hashed = password_hash($secret, PASSWORD_BCRYPT, ['cost'=>11]); Python: hashed = bcrypt.hashpw(secret, bcrypt.gensalt(11)) 

And I used this [PHP] to check above:

 <?php $secret = 'secret12345620161116'; $php = '$2y$11$rMqK7PhWtYd3E6yqqor0K.p2XEOJqbxJSrknLLWfhqZKsbYRa1YRa'; // output from PHP  $python = '$2b$11$yWzCNB4dfIIVH2FLWWEQ/efSmN/KlVmLq.MGJ54plgedE1OSQgvPu'; // putput from python script $php_needs_rehash = password_needs_rehash($php, PASSWORD_BCRYPT); $python_needs_rehash = password_needs_rehash($python, PASSWORD_BCRYPT); echo 'php_needs_rehash: '.$php_needs_rehash."\n"; echo 'python_needs_rehash: '.$python_needs_rehash."\n"; echo "\n"; echo "php_info:\n"; print_r(password_get_info($php)); echo "\n"; echo "python_info:\n"; print_r(password_get_info($python)); echo "\n"; echo "php_verified: ".password_verify($secret, $php)."\n"; echo "python_verified: ".password_verify($secret, $python)."\n"; echo "\n"; ?> 

With the following output:

 php_needs_rehash: 1 python_needs_rehash: 1 php_info: Array ( [algo] => 1 [algoName] => bcrypt [options] => Array ( [cost] => 11 ) ) python_info: Array ( [algo] => 0 [algoName] => unknown [options] => Array ( ) ) php_verified: 1 python_verified: 1 

So now I'm really confused, as the server still does not recognize my hashed python key, unless I replace "$ 2b" with "$ 2y" as suggested by richardhsu in the comments, that is.

+6
source share
1 answer

Technically, these are both different versions of bcrypt or crypt-blowfish

in php the prefix is ​​$ 2y $ 10 $ in python the prefix is ​​$ 2b $ 11 $

This means that cost ratios are slightly different from 10 versus 11, respectively, in your update, cost ratios are fixed as at level 11

Another part of the prefix indicates that php uses CRYPT_BLOWFISH hashing, where python uses bcrypt, which is based on the Blowfish cipher.

Due to these differences, 2 passwords are not interchangeable.

0
source

Source: https://habr.com/ru/post/1012385/


All Articles