好的,开始翻译吧。
我已经建立了一个[简单的]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());
?>
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])
每个命令的输出如下所示:
PHP:
secret12345620161116
$2y$10$/WUBS2RkTlfcgPxvmqYRI.EkBD/CPgnpE9rYvOqweERgSwFeENUDO
5.6.24
Python:
secret12345620161116
$2b$11$9v/l6KglHiNgOybw1Y8jWeCFHiAfv.cguO1Qmc7Noe4azSluoBeHO
2.7.11
显然,它们是不同的,这就是关键所在,但当您将Python输出传递给PHP password_verify()函数时,它返回False。 PHP输出可以正常验证。
我肯定会漏掉一些东西,但是我无论如何都找不到它。 我已经尝试使用不同的salt选项,但没有成功。 我错过了什么? 它们两个不兼容吗? 如果是真的,那看起来很傻。
非常感谢您聪明的网络人士。
更新:
[我已经使用以下2行代码更新了脚本]
PHP: $hashed = password_hash($secret, PASSWORD_BCRYPT, ['cost'=>11]);
Python: hashed = bcrypt.hashpw(secret, bcrypt.gensalt(11))
我已经使用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";
?>
以下为输出结果:
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
所以,现在我真的很困惑,因为服务器仍然无法识别我的Python哈希密钥,如果我不按照richardhsu在评论中建议的那样用"$2y"替换"$2b"。
$2y$
作为“bcrypt”算法标识符。显然,Python使用不同的标识符。此外,下一个值是成本。不同的成本意味着哈希将重复的循环次数不同。尝试将PHP成本更改为像Python哈希一样的11
(可以设置为password_hash的选项之一),看看它是否与Python哈希减去算法相匹配。 - Jonathan Kuhnpassword_verify()
函数会查看哈希值中的成本并相应地进行验证。你到底在比较什么? - M. Eriksson