前开发人员使用带有SHA256算法的PHP hash()
函数来存储密码哈希值。为了提高系统的安全性,我想开始使用带有Blowfish算法的crypt()
(遗憾的是我们没有PHP 5.5,因此password_hash()
不可用)。
由于SHA256是一种不可逆的哈希算法,有没有办法开始使用带有盐渍密码的crypt()
而不要求所有人重置密码?
答案 0 :(得分:3)
然后你应该使用compatibility library。当你移动到5.5时,它将使你更容易。
在不询问用户密码的情况下重新散列...好吧,您可以等到下次用户登录,然后使用password
扩展程序的password_verify()
功能。如果失败,那么你可以回退旧的SHA256哈希。如果SHA256哈希匹配,那么您可以使用password_hash()
重新密码,并将其保存在旧哈希的位置:
if (password_verify($password, $hash)) {
// Matches...
} elseif (hash('sha256', $password) == $hash) {
// Matches...
$newHash = password_hash($password);
// Save $newHash in the old hash's place
} else {
die('Invalid password...');
}
技术上可能会破坏很多哈希值,但是有太多问题(你不会得到所有这些,它很可能不可行,甚至可能不会是合法的等等。)。
答案 1 :(得分:3)
您可能需要考虑的另一种方法是哈希链接:因为您无法反转SHA256,所以只需将新哈希函数定义为crypt(sha256($passwd))
即可。由于您可能已经为您的所有密码存档sha256($passwd)
,因此可以crypt()
每个人使用适当的盐来更新现有的哈希值(无需等待用户)登录)。
答案 2 :(得分:1)
这是一个可能的解决方案:
在用户表中添加一列,以指示用户密码上使用了哪种哈希方法。在登录时,您知道用户的密码,因为他刚刚输入密码,所以一旦传递了当前的哈希值,请从密码中创建一个新密码并更新标志列
这假设您通过互联网传递自由文本密码,除非您使用SSL,否则您不应该这样做。
或者,如果您在发送密码之前在客户端上散列密码,请更新客户端软件以处理两种散列算法并发送两者。使用您的标志来确定要检查的内容。
在这两种情况下,一旦您的所有用户(或大多数用户)切换,请删除旧的哈希并强制其余用户使用该问题。
答案 3 :(得分:0)
我假设您从未存储过明文用户帐户密码,因为这真的是一件非常糟糕的事情。因此,您不再拥有创建新密码摘要所需的数据。
我认为你需要每个人都更新他们的密码。
答案 4 :(得分:0)
可能还有其他更快,更有效的方法,但如果你想这样做而不影响你的用户,我就是这样做的 -
向表中添加另一列,一个可以为True或False的基本标志。将其默认为false。然后实现以下伪代码:
if(flag=true)
{
use crypt() and authenticate user
}
else
{
use hash() and authenticate user
use crypt() on the provided password (once authenticated)
update the record to put the new password into the table
set flag=true
}
基本上它会检查密码是否更新,如果不是,则更新密码。一旦用户完成转换,您最终可以关闭此功能。但由于它几乎没有任何负载,我建议保留它!
它有点迂回,但它将为您的用户提供最少量的工作,并且它将在后台运行而不会给出任何关于它发生的迹象!
答案 5 :(得分:0)
我想说使用标记字段来注释先前已经散列过哪些用户,然后加密现有散列。对于在标记字段中具有true的任何人在进行身份验证时变为两步过程时,请对密码进行哈希处理,然后将其加密以进行匹配检查。
每当他们更新密码时,您都会将标记字段设置为false。即进入并且只是用于匹配检查的地穴。
答案 6 :(得分:0)
是的,您需要做的是添加一个存储crypt()
输出的额外列。当用户登录并且密码成功hash()es
到您在数据库中的密码时,您现在可以crypt()
该密码,并从数据库中删除旧的hash
。
这仅在用户登录时有效,因此您将有一段时间某些用户使用旧系统,而某些用户正在使用新系统。