我们的应用程序使用bcrypt将正常密码以散列格式存储,成本(轮次数)为15.检查密码的有效性在我们的生产服务器上花费的时间不超过1秒,这对于每次执行一次是可接受的会议行动。
我们现在正在开发和保护我们的应用程序。我们将为用户提供设置5位数密码的机会,这是第一次使用他们通常的凭据(登录名和密码)登录后。
使用较低的bcrypt成本(即13)来散列这些密码是否合理?
我的考虑因素:
答案 0 :(得分:2)
使用较低的bcrypt成本(即13)来散列这些密码是否合理?
简而言之,是的。或完全废弃bcrypt(见下文)。
我认为这里有一些关于key stretching和KDFs(即bcrypt)的混淆,以及它们与离线和在线攻击的关系。
如果有人从您的服务器中提取哈希值并继续运行离线暴力破解或猜测对它们的攻击,那么像bcrypt这样的算法可以防止密码被识别。
Bcrypt并不是为了防止在运行时针对您的应用程序进行密码猜测攻击。在这里,您可以使用服务器端应用程序逻辑来检测针对同一帐户的暴力,然后对该尝试进行速率限制。例如,在特定时间段内针对同一用户名进行了一定数量的错误猜测后,故意延迟响应。
设备在服务器上注册一个字符串,包括时间,设备ID和随机字符串。
假设设备ID是128位UUID,您已经有一个128位的标识符,如果正确随机,它实际上是不可破解的。但是,GUIDs are designed to be unique, not random正如您在其他问题中提到的那样,任何知道此值的人都已经在那里破解您的身份验证。
我会废弃这个并简单地生成一个随机的128位字符串,用作"安装ID"使用加密安全的伪随机数生成器(CSPRNG)。由于这已经非常强大,因此无需通过密码拉伸算法或密钥派生函数(如bcrypt)对其进行加盐或运行。服务器端存储版本的SHA-256哈希就足够了。
可以使用17位表示5位密码。 bcrypt成本为13将有效地使该密码具有30位的强度。这远远低于NIST recommendation of 80 bits。
然而,让我们考虑一下这意味着什么。 Bcrypt用于保护服务器端哈希不被使用单词列表猜测(或者在这种情况下是数字列表,范围从00000到99999)。如果您的128位安装ID存储在服务器上并且攻击者设法访问您的用户表,即使他们确实破解了存储在bcrypt中的5位数密码,他们也无法以用户身份登录,因为他们不知道如何生成SHA-256哈希 - 它们没有安装ID。遍历每个可能的128位值并查明它是否散列到存储值是完全不可行的。彩虹表太大了,无法存储2 128 组合。
为了简单起见,我很想废弃bcrypt获取密码,只需将SHA-256(passcode + 128 bit random installation ID)
存储在服务器上即可。密码可以作为"安装ID"的盐。因此,用户更改其密码将生成一个完全不同的哈希值,存储在服务器端。
请注意,上面假设设备和帐户之间存在一对一的关系。如果每个设备使用多个帐户,则应为每个帐户添加额外的盐(例如64位) - 否则选择相同密码的两个用户将具有相同的服务器端散列值。安装ID"还有一个额外的安全风险。现在为另一个用户所知,以及与其他用户共享客户端设备所带来的所有其他风险(例如,物理安全方面或恶意软件风险)。
答案 1 :(得分:1)
单独对5位数密码进行散列并不是很感兴趣,因为它可以很容易地强制执行(只有100000个可能的值)。我试着看看是否有办法将密码与用户密码一起存储。