用无效的哈希替换 bcrypt 哈希是否会导致没有可能的工作密码?

信息安全 密码 哈希 bcrypt
2021-09-01 19:47:23

我有一位经理喜欢通过用简单的破折号 ( -) 替换数据库中现有的 bcrypt 哈希来“停用”帐户。

bcrypt 哈希家族中的一个破折号

这似乎有效,因为旧密码不再有效,并且没有任何其他密码可以匹配的有效 bcrypt 哈希。但我很好奇,这是有效的还是会产生安全风险?

这是使密码无效的有效方法还是会产生更大的安全风险?

此特定实现使用 PHP password_verify函数,但我希望答案集中在任何一般实现上。请不要关注我经理的不良做法。我们还有一个布尔字段,用于将用户设置为非活动/活动,我认为这更好、更安全,但不是我希望答案关注的内容。

4个回答

在禁止合法登录尝试方面,这很好。除非您使用非常奇怪的哈希函数,否则不会有任何值映射到-,并且如果数据库也被盗,它可以防止对缺失值的暴力攻击,这是一个积极的(他们不太可能,鉴于使用 bcrypt,但这适用于即使实现使用一种糟糕的方法来存储密码 - 几乎除了纯文本之外的任何东西)。

不利的一面是,如果数据库被占用,它会稍微降低其他帐户的安全性——攻击者可以暴力破解的记录更少。如果他们注意了,他们可能应该删除标记为非活动但仍然存在的记录。我确实说“稍微”...

其他风险可能是,如果有任何访问方法允许绕过哈希方法进行比较(例如,您有一个旧方法允许出于某种原因提供完整哈希) - 在这种情况下,如果您没有检查活动仔细检查状态,它可能允许通过提供破折号进行访问。理想情况下,如果是这种情况,请删除此访问方法。

无效的密码散列(通常是“*”)会真正禁用密码身份验证,因为实际上没有办法提供将散列到它的值。但是,如果有其他身份验证方法(例如通过 ssh 私钥),则无效的密码哈希不会“停用”帐户。事实上,这是强制仅使用密钥身份验证的常见方式:无效密码与 .ssh 公钥结合使用~user/.ssh因此密码列中的无效哈希不应被解释为“帐户不活动”,而是“密码验证被阻止”。

如果密码访问是唯一可用的路径,则无效哈希可以说优于显式标记,因为它不需要软件支持:如果/etc/password有一个activeuser列并且我在密码字段中留下有效密码时使用了它,则某些工具可能会忽略该activeuser字段.

当然,一个很大的区别是被标记为“非活动”的用户仍然可以登录,除非您的服务器检查该标志并正确处理该尝试。此外,标志可能会被移除,有效地恢复原始状态,而将哈希更改为“-”则无法恢复,除非将密码哈希保存在其他地方。根据您的应用程序,这可能是也可能不是所需的行为。

这种方法不会产生安全风险,因为有权访问您的数据库的攻击者只能看到该用户不应该能够登录。正如您正确指出的那样,没有 bcrypt 哈希可以匹配“-”,如单独的格式不匹配。

正如 schroeder 在评论中所说,这不是一个不好的做法,而是一个防止用户登录的常见概念,无需修改登录机制以考虑您的“非活动”标志(尝试登录的非活动用户被隐式拒绝)。

安全散列的目的是使破解数据库中的密码变得困难。如果可以从“简单哈希”中破解甚至猜出密码,那么帐户密码就有风险。

但是,这还不是全部。如果目的只是使任何人无法从客户端使用或猜测密码,那么它就可以正常工作。这种方法已经使用了很长时间。但是后端的密码条目被削弱了。如果有其他控制措施,这可能会很好,并且帐户泄露的风险和影响很低。