PHP password_verify()vs Python bcrypt.hashpw()

kdo*_*gan 6 php python bcrypt password-encryption

所以,对吧.

我已经设置了一个[简单的] PHP REST API,我通过X-API-KEY标头密钥接收一个哈希密码.当与另一个PHP脚本连接时,这很有效,并且通过PHP的password_hash()方法对短语进行哈希处理.但是,当我尝试通过Python和Requests库与API接口时,密钥被拒绝.以下是一些示例:

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());
?>
Run Code Online (Sandbox Code Playgroud)

蟒蛇:

#!/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])
Run Code Online (Sandbox Code Playgroud)

每个的输出如下:

PHP:
    secret12345620161116
    $2y$10$/WUBS2RkTlfcgPxvmqYRI.EkBD/CPgnpE9rYvOqweERgSwFeENUDO
    5.6.24

Python: 
    secret12345620161116
    $2b$11$9v/l6KglHiNgOybw1Y8jWeCFHiAfv.cguO1Qmc7Noe4azSluoBeHO
    2.7.11
Run Code Online (Sandbox Code Playgroud)

现在,显然它们是不同的,这就是重点,但是当你将Python输出传递给PHP的password_verify()函数时,它返回False.PHP输出验证就好了.

我必须在这里找到一些东西但是,对于我的生活,我找不到它.我尝试使用不同的盐选项但没有成功.我错过了什么?这两个是不兼容吗?这看起来很愚蠢,如果这是真的.

谢谢先进的智能互联网人士.

UPDATE

[我已使用以下2行更新了脚本以进行测试]

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

我用这个[PHP]来验证上面的内容:

<?php
$secret = 'secret12345620161116';

$php    = '$2y$11$rMqK7PhWtYd3E6yqqor0K.p2XEOJqbxJSrknLLWfhqZKsbYRa1YRa'; // output from php script
$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";
?>
Run Code Online (Sandbox Code Playgroud)

使用以下输出:

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
Run Code Online (Sandbox Code Playgroud)

所以,现在我真的很困惑,因为服务器仍然无法识别我的python哈希密钥,如果我没有按照richardhsu在评论中建议的"$ 2y"替换"$ 2b",那就是.

Wal*_*sen 2

从技术上讲,它们都是 bcrypt 或 crypt-blowfish 的不同版本

在 php 中,前缀是 $2y$10$ 在 python 中,前缀是 $2b$11$

这意味着成本因素略有不同,分别为 10 和 11,在您的更新中您已将成本因素固定为 11

前缀的另一部分表示 php 使用 CRYPT_BLOWFISH 哈希,而 python 使用基于 Blowfish 密码的 bcrypt。

由于这些差异,这两个密码不可互换。