Kap*_*ost 2 php database security passwords django
我有一个问题,因为我有一个用户数据库,他们的密码是用Django(pbkdf2)保护的.所以'123'看起来像这样:
pbkdf2_sha256$20000$MflWfLXbejfO$tNrjk42YE9ZXkg7IvXY5fikbC+H52Ipd2mf7m0azttk=
Run Code Online (Sandbox Code Playgroud)
现在我需要在PHP项目中使用这个密码,我不知道如何比较它们.
pbkdf2_sha256$20000$MflWfLXbejfO$tNrjk42YE9ZXkg7IvXY5fikbC+H52Ipd2mf7m0azttk=
让我们打破这个.的$是分隔符:
pbkdf2_sh256 表示PBKDF2-SHA256,即 hash_pbkf2('sha256', ...)20000 是迭代计数MflWfLXbejfO 是盐tNrjk42YE9ZXkg7IvXY5fikbC+H52Ipd2mf7m0azttk= 可能是哈希.这是从PHP验证哈希所需的所有信息.您只需要:
hash_pbkdf2() 从用户提供的密码生成新的哈希hash_equals() 将生成的哈希与存储的哈希进行比较这个功能应该工作(PHP 7+):
/**
* Verify a Django password (PBKDF2-SHA256)
*
* @ref http://stackoverflow.com/a/39311299/2224584
* @param string $password The password provided by the user
* @param string $djangoHash The hash stored in the Django app
* @return bool
* @throws Exception
*/
function django_password_verify(string $password, string $djangoHash): bool
{
$pieces = explode('$', $djangoHash);
if (count($pieces) !== 4) {
throw new Exception("Illegal hash format");
}
list($header, $iter, $salt, $hash) = $pieces;
// Get the hash algorithm used:
if (preg_match('#^pbkdf2_([a-z0-9A-Z]+)$#', $header, $m)) {
$algo = $m[1];
} else {
throw new Exception(sprintf("Bad header (%s)", $header));
}
if (!in_array($algo, hash_algos())) {
throw new Exception(sprintf("Illegal hash algorithm (%s)", $algo));
}
$calc = hash_pbkdf2(
$algo,
$password,
$salt,
(int) $iter,
32,
true
);
return hash_equals($calc, base64_decode($hash));
}
Run Code Online (Sandbox Code Playgroud)
如果您需要遗留PHP 5支持,删除string前缀和: bool函数定义将使其在PHP 5.6上运行.我不建议尝试为早于5.6的PHP版本添加向后兼容性; 如果您发现自己处于这种情况,则应更新服务器软件.