是否有办法将MD5
的密码转换为可以由password_verify()
验证的密码?
我在Crypt维基百科页面上读到"MD5
密码哈希的可打印形式从$1$
开始。"
因此我给了这个机会(没有任何运气):
$password = "abcd1234";
$md5hash = "$1$".md5($password);
var_dump(password_verify($password, $md5hash));
是否有办法使password_verify()
与MD5
密码工作?
问题的原因:我有一个旧的系统,其中密码存储为MD5
哈希。我想开始使用更安全的Password Hashing API
。如果我能够将现有的密码哈希值转换为与password_verify()
一起工作的东西,我可以只需更新数据库条目(将$1$
添加到所有密码哈希值),并且我的程序将使用以下代码完美地工作(我不必为旧的MD5
密码做特殊情况):
$password; // Provided by user when trying to log in
$hash; // Loaded from database based on username provided by user
if(password_verify($password, $hash)) {
// The following lines will both update the MD5 passwords
// and all passwords whenever the default hashing algorithm is updated
if(password_needs_rehash($hash, PASSWORD_DEFAULT)) {
$hash = password_hash($password, PASSWORD_DEFAULT);
// Store the new hash in database
}
// User is logged in
} else {
// User is not logged in
}
你不能那样做。
您可以做的是通过password_hash()
对已经md5哈希的密码进行哈希,并在数据库中为这些旧密码添加额外的标志,以便您知道之后要对它们进行双重验证。
示例代码:
<>之前$passwordCompare = ($passwordIsOldFlag === true)? md5 (passwordInput美元): $ passwordInput;if (password_verify($passwordCompare, $ passworddhash)){if ($passwordisOldFlag === true){$ passwordnewwhash = password_hash($ passworddinput, PASSWORD_DEFAULT);//在这里,您将使用新的纯bcrypt散列更新数据库//也将passwordIsOldFlag设置为0}}之前注意:MD5生成的字符串长度为32个字符,而password_hash()
最小为60个字符。
阅读手册:
- http://php.net/manual/en/function.password-hash.php
当你决定使用password_hash()
或兼容包(如果PHP <5.5) https://github.com/ircmaxell/password_compat/,重要的是要注意,如果您当前的密码列的长度低于60,它将需要更改为(或更高)。手册建议长度为255。
您需要更改列的长度并重新使用新的散列以使其生效。
md5
(或任何其他散列算法-参见hash_algos()
的完整列表)每次都会将某些内容散列为常量(相同),换句话说:
'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
...
但是password_hash($password, $algo)
每次都会把一个东西散列成一个新的东西,换句话说:
'1234' ---password_hash---> '$2y$10$VXj5/N79aVolZQHJa.wdUub4C1uifXCNGRVKVUIYnsuRGs/wnXU/S'
'1234' ---password_hash---> '$2y$10$BjSPyCyZU2Rui5MtL5MLC.bkLGbUxf/f9NshALvTc39lhemoWZFC6'
'1234' ---password_hash---> '$2y$10$WXGX/6dCLbJN77MKNNVbCej9Fya2fQGvPjAMLuU3a6zGCDuBMisbm'
'1234' ---password_hash---> '$2y$10$sqkB2ZK7BanIHTRZIKUHi.TVdseZE.GSMghBhuT7mDC9GrjW9g6Ky'
所以一个hash_verify_kind_function()只需要password_hash()
的哈希,因为你可以用md5(或任何)哈希你的字符串,只是检查它是否都等于这是非常愚蠢的工作,因为在这种情况下,你不需要先用md5哈希它!因为实际上md5哈希并没有用于密码哈希(因此验证)