在数据库中存储 PHP crypt() 结果是否安全


Is it secure to store a PHP crypt() result in the db?

例如,对于河豚,它返回如下内容:

$2a$12$DEzG.CRsHpxpTOAHooQ.wuR6Xe9h6PxFPhOcOvf.lqDNw1TVYVnEO

它包含有关哈希算法类型的信息,并且包含盐。很多资源说只将此值存储在数据库中,这将是安全的。但是,有人不能根据这些值测试一个通用的密码列表来破解其中一些吗?

密码散列的安全性并非来自信息的机密性。您已经丢弃了实际的机密,即作为哈希值基础的密码。剩余的哈希只是这些原始数据的一种指纹。安全性来自这样一个事实,即不可能从哈希中派生原始数据。唯一的可能性是尝试所有可能的密码,看看哪个会产生相同的哈希。这里的安全性来自这样一个事实,即这在计算上非常昂贵,并且不太可能在有用的时间内成功。

引入盐只是为了防止某人使用一组已经预先计算的已知哈希密码,迫使攻击者实际上使用唯一的盐重新哈希所有可能的密码。盐本身不是秘密,哈希算法也不是秘密。

简而言之:是的,该值存储在数据库中是绝对安全的。

crypt()生成的哈希专门用于存储。无论您的密码哈希方案是什么,如果有人掌握了您的数据库内容,他们将能够暴力破解您的密码,并且您根本没有不存储密码哈希的选项。crypt()应用的算法是专门选择的,因为它们需要大量时间来计算哈希;当您只测试一个密码时,这并不明显,但是暴力破解数千个密码变得不切实际地缓慢。

但是有人不能只测试一个常见的密码列表吗 这些价值观来破解其中的一些?

无论密码如何存储,您始终可以这样做。crypt功能不会阻止这种情况,但它会使它非常慢。如果用户使用非常通用的密码(如123456),则世界上没有哈希算法可以保护他。

如果您不允许这些简单的密码并使用良好的哈希算法(crypt() 供应),那么您已经尽力保护密码。

如果有人可以访问您的数据库,那么无论哪种方式,他们都可以访问 salt,因为您应该为每个用户密码使用不同的 salt(您很可能会将其存储在数据库中)。

盐的目的是让彩虹表不起作用。个人必须重新散列密码+盐的每个组合才能确定密码。你在每个密码上使用不同的盐,所以他必须为每个密码重新生成数百万个哈希。

更多关于地穴的好信息可以在这里找到:为什么 PHP crypt() 会在哈希前面加上盐?