如果这纯粹是一个只读事件并且他们得到的只是散列版本,那应该不是问题。话虽如此,我更喜欢使用hash() 函数而不是password_hash(),但这只是我个人的喜好。
唯一的问题是读取 php 文件并获得散列密码的攻击者是否有办法反转它(即彩虹表)。在这种情况下,您的系统变得不安全。这就是我偏爱hash() 而不是password_hash() 的原因。与hash()。要生成散列形式,我可以说:
$HashedMasterPassword = hash('md5', $MasterPassword . "MyMD5Salt") . hash('sha256', $MasterPassword . "MyShaSalt");
然后在我上传的代码中,我可以获取上述代码的输出 ($HashedMasterPassword) 并将该字符串硬编码到我的代码中。这增加了两种不同的盐,两种不同的散列函数,它减少了彩虹表攻击的可能性已经很低,因为攻击者需要同时发生 md5 + 第一个盐和 sha256 + 第二个盐的冲突。这是,我敢说,不可能。当然,鸽子洞效应表明这是可能的,而且确实如此,但这几乎是不可能的,我不会为此烦恼。
话虽如此,如果你真的想的话,使用password_hash() 并存储该哈希值是可以的。我只是个人不喜欢它。
编辑:添加实现细节
根据 cmets,我相信对于如何实施这一点存在一些混淆。假设我的主密码是thisIsMyPassword(我知道超级机密和超级安全)。好吧,我们需要生成硬编码的散列形式。硬编码的散列形式可以通过以下方式找到:
$MasterPassword = "thisIsMyPassword";
$HashedMasterPassword = hash('md5', $MasterPassword . "MyMD5Salt") . hash('sha256', $MasterPassword . "MyShaSalt");
echo $HashedMasterPassword;
重要提示:您不会将其上传到服务器。这将仅用于生成哈希,然后应将其永久删除。
它的输出是:6dcfc45fba2fff44b7cfc8df7245a1b7804c88d63a82ac2ba33e0de32ab7f20c5afe2c1784e87f1bae8a4f91f1a84833
因此,在需要主密码才能覆盖的代码中,您应输入:
$MasterHash = '6dcfc45fba2fff44b7cfc8df7245a1b7804c88d63a82ac2ba33e0de32ab7f20c5afe2c1784e87f1bae8a4f91f1a84833';
$SubmittedMasterPass = $_POST['MasterPassword'];
$HashedVersionOfSubmittedMasterPass = hash('md5', $SubmittedMasterPass . "MyMD5Salt") . hash('sha256', $SubmittedMasterPass . "MyShaSalt");
if($MasterHash !== $HashedVersionOfSubmittedMasterPass){
die('Override Failed. Reason: Wrong Password.');
}else{
// User has successfully logged in using the master password.
}
再次根据来自 cmets 的信息进行澄清,这比仅使用 SHA256 更安全,因为必须找到一个暴力破解的主密码,当MyMD5Salt 附加到它的末尾时会产生6dcfc45fba2fff44b7cfc8df7245a1b7,它也当MyShaSalt 附加到它的末尾时,必须产生804c88d63a82ac2ba33e0de32ab7f20c5afe2c1784e87f1bae8a4f91f1a84833。这意味着碰撞必须满足两种不同的算法,这比单独满足 Sha256 算法要困难得多。
但是,正如 cmets 中所指出的,这确实需要多几毫秒的时间来处理;因此,如果减少执行时间是您的重中之重,那么可能建议仅单独使用 Sha256,而不是结合使用 MD5 和 Sha256。