Security 在内存中存储不太安全的密码哈希,作为性能折衷?

Security 在内存中存储不太安全的密码哈希,作为性能折衷?,security,hash,passwords,cryptography,password-hash,Security,Hash,Passwords,Cryptography,Password Hash,我目前正在从事一个涉及存储和验证密码的项目。密码经过100000次迭代散列,然后保存到数据库中,稍后在用户登录时检索和验证。它工作得很好,因为在低负载期间,哈希需要约1秒的时间生成,并且大多数用户认为延迟是可以接受的 问题是,随着系统拥有越来越多的用户(~100个并发用户),散列现在已经耗尽了cpu,需要超过6秒的时间来生成——这导致登录时间非常缓慢,不幸的是,系统有一个无状态api,每次调用都需要验证密码 据我所知,为了避免bruce force攻击,我们希望使哈希计算变得昂贵,但考虑到攻击者

我目前正在从事一个涉及存储和验证密码的项目。密码经过100000次迭代散列,然后保存到数据库中,稍后在用户登录时检索和验证。它工作得很好,因为在低负载期间,哈希需要约1秒的时间生成,并且大多数用户认为延迟是可以接受的

问题是,随着系统拥有越来越多的用户(~100个并发用户),散列现在已经耗尽了cpu,需要超过6秒的时间来生成——这导致登录时间非常缓慢,不幸的是,系统有一个无状态api,每次调用都需要验证密码

据我所知,为了避免bruce force攻击,我们希望使哈希计算变得昂贵,但考虑到攻击者访问内存转储的可能性远小于访问数据库的可能性,我想实现一种折衷方案,在成功登录后,我将以较少的迭代次数(例如,5000次)对密码进行哈希并在内存中存储一段短时间。如果传入的请求希望验证相同的用户id,我会使用内存中的不太安全的版本进行验证,否则我会使用数据库中更安全的版本。这可以通过访问数据库来防止攻击,在高负载情况下,大多数请求都可以通过内存中成本较低的哈希来满足

我意识到这不太安全,但这是合理的权衡吗?有什么我应该注意的地方吗


Adrian

此哈希/身份验证通常只在每个用户/会话登录时执行一次;在这之后,某种形式的身份验证令牌/临时值(例如cookie)通常会接管。是否有100次针对上述密码存储的并发身份验证尝试?此外,我不确定如何从“更散列/安全”的散列中获得“更少散列/安全”的散列,因为能够这样做意味着散列是可逆的。在任何情况下,如果确实存在此类瓶颈,则可能值得将身份验证卸载到其他系统/硬件上。不幸的是,我们的API是无状态的,因此没有会话;来自客户端的每个调用都将是一个新的登录。如果我们成功地验证了密码,我就可以再次获得客户端文本密码(通过的密码),并且我可以从中生成不太安全的版本。重复哈希的整个要点是减缓暴力攻击以“阻止”这种向量。因此,您必须计算数据的期望值-如果所述散列数据可用,但由于某些不太可能的原因没有暴露原始信息-攻击者在暴力情况下会使用多少资金/硬件?数据越重要,攻击者投入的资金就越多。通过减少重复散列(通过某个因素),这只是一个数字游戏,一个坚定的攻击者可以更快地(通过某个因素)生成所说的散列。我想我不明白。您说您的系统是无状态的,但您仍挂起数据(密码的特殊版本),将其与浏览器持有的密钥(用户ID)关联,并挂起它一段临时时间(15分钟)。对我来说,这听起来很像一次会议。