如何在 flutter(dart) 应用程序和 PHP 网站之间使用 SALT+HASH 密码 saving/checking?

How can I utilise SALT+HASH password saving/checking betwen a flutter(dart) app and a PHP website?

我在我的 flutter 应用程序中编写了一个 salt/hash 密码函数,使用 PBKDF2 效果很好。这会将 salt 和 hash 保存在 mysql 数据库中的单独字段中。我有一个功能可以获取盐并根据用户输入的密码生成检查 - 到目前为止一切顺利。

我现在正在编写一个使用相同数据库的基于PHP的网站,我希望能够使用相同的用户名:pwd-hash/salt登录该网站。

我的问题是我无法在 PHP 中找到与 flutter/dart 代码结果相同的代码。

我的工作 flutter 代码使用 password_hash

var generator = new PBKDF2();
var salt = list.first.strPwdSalt; // this is the salt grabbed from DB
var hash = generator.generateKey(pwd, salt, 1000, 32);

这会输出一个我保存到数据库中的列表,以后比较结果的操作工作正常(因为它始终是一个列表,作为字符串存储在数据库中)

我希望以下 PHP 代码可以使用 hash_pbkdf2 函数工作:

$password = "andy";
$iterations = 1000;   
$salt = "wh9wRLd2cZYrdESln1JSzA=="; // Manually grabbed SALT from DB

$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 32);
echo $hash;

此输出:efeb557dbb1b774333420687411bf8b9

我无法将上面的字符串转换为 List,也无法在 flutter 中对 List 进行任何操作以使其具有相同的格式。

经过多天的谷歌搜索,我被卡住了,我希望这是一个相当常见的用例??

谢谢

您的 Flutter 代码生成了一个包含 32 个数字字符代码的列表。对于您问题中的示例密码和盐,该列表是:

[239, 235, 85, 125, 187, 27, 119, 67, 51, 66, 6, 135, 65, 27, 248, 185, 33, 185, 216, 106, 17, 57, 90, 13, 105, 61, 145, 148, 86, 32, 182, 94]

PHP的hash_pbkdf2函数可以生成相同的字符,但你必须告诉它return一个二进制结果:

$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 32, true);

(注意最后一个 true 参数)。

此 returns 的二进制字符串与您在 Flutter 应用程序中获得的列表的字符串表示相匹配,因此这可能已经足以让您匹配存储在数据库中的字符串值。

如果您存储在数据库中的字符串不是原始二进制字符串,而是十六进制表示形式,您可以通过将 hash_pbkdf2 的结果传递到 [=17=,在 PHP 中获取该字符串]:

$hex = bin2hex($hash);
// efeb557dbb1b774333420687411bf8b921b9d86a11395a0d693d91945620b65e

如果这还不够并且您需要 PHP 中的数字字符代码数组,您可以遍历二进制字符串并使用 ord 函数构建一个数组来自 PHP 字符串的字符代码:

$characters = array();

for ($i=0; $i<strlen($hash); $i++) {
    $characters[] = ord($hash[$i]);
}

print_r($characters);

/*
Array
(
    [0] => 239
    [1] => 235
    [2] => 85
    [3] => 125
    [4] => 187
    [5] => 27
    [6] => 119
    [7] => 67
    [8] => 51
    [9] => 66
    [10] => 6
    [11] => 135
    [12] => 65
    [13] => 27
    [14] => 248
    [15] => 185
    [16] => 33
    [17] => 185
    [18] => 216
    [19] => 106
    [20] => 17
    [21] => 57
    [22] => 90
    [23] => 13
    [24] => 105
    [25] => 61
    [26] => 145
    [27] => 148
    [28] => 86
    [29] => 32
    [30] => 182
    [31] => 94
)
*/

现在 $characters 是一个与你在 Flutter 中得到的列表完全匹配的数组。