使用 bcrypt 时选择的最大密码长度是多少?

信息安全 密码 密码策略 bcrypt
2021-08-09 01:00:53

当我使用 KeePass 为 GitHub 生成密码时,我在 GitHub 网站上收到一条消息,说密码长度限制为 72 个字符。看起来很奇怪,它不是 2 的幂,所以我用谷歌搜索了一下,似乎 72 是 brypt 算法的最大字节。因此,将数字限制为 72 似乎是合乎逻辑的,因为更长的密码无论如何都会被截断为 72。

然后我为 Discord 生成了密码,看起来最大长度为 128 个字符。但我想我会检查密码中的前 72 个字符是否足够。是的,我的 128 个字符的密码也被截断为 72 个第一个,所以我猜 Discord 也在使用 bcrypt。

所以问题是,将密码长度限制设置为 72 个字符更好还是让用户选择更长的密码(多长?128、256 字节?)即使它们会被截断?

第一个标准是安全性,然后才是可用性、存储或实施难度。

2个回答

我不赞成静默截断,因为它会误导用户认为他们的整个密码都被接受了,而事实并非如此。如果需要,我希望系统只设置最大长度,并在密码输入期间限制用户。 我听说过的一个糟糕情况是代码更改开始处理超出之前最大长度的字符,突然更长的密码用户无法登录。系统只有前 72 个字符的记录,而它们的较长字符串没有t 匹配没有旧系统截断。这会导致用户感到沮丧。

作为 72 个字符截断的替代方法,您应该考虑使用盐渍 SHA-256 之类的东西对密码进行预哈希处理。允许考虑超过 72 个字符的用户的整个密码字符串,同时仍然提供 bcrypt 的计算保护。请阅读下面链接的问题和评论,以了解此方法的一些安全权衡。

我通常是反对愚蠢限制的人,但我不得不怀疑:谁认真使用超过 72 个字符的密码?这么长的密码很难输入,所以几乎可以肯定它是一个机器人(或密码管理器中的 ctrl+v)。机器人* 和密码管理器并不关心他们是否必须记住随机字母数字字符串而不是密码。

假设他们不使用特殊字符,即每个字符有 26+26+10=62 个可能性,假设最多 72 个字符。这允许62^72 = 1.13*10^129可能性。转换为熵位,一个更易于管理的数字,我们得到log(62^72)/log(2) = 428.7熵位。

最后我检查了一下,即使是后量子,256 位密钥也被认为是合理的,所以这应该足够了

在极少数情况下它是密码短语,让我们使用一个非常标准的字典:我的 Debian 系统上的默认字典。经过一些标准的修剪(不区分大小写;删除所有格变体,例如“horse's”而不是“horse”),它包含大约 50k 个单词。这个数学我不太确定,但我认为这意味着每个单词,当随机选择时(你应该使用密码短语),都会给出一些log(50000)/log(2)=15.6熵。平均字长一般认为是 5 个字符,加上一个空格,所以 72 大约是 12 个字。

这归结为15.6*12 = 187.372 个字符的密码短语中的熵位。作为下限,因为我的 dict 不包含所有单词。我会说你很好。

真正愚蠢的限制是 bcrypt 的 72 个字符,但如果这是您必须使用的,我认为这是为用户设置的合理限制。

* 好吧,好吧,也许机器人会关心。再次询问我何时有机器人权利修正案。

编辑:我正在回答标题。要解决您帖子中的其他问题:

所以问题是,将密码长度限制设置为 72 个字符更好还是让用户选择更长的密码 [...] 即使它们会被截断?

不要默默地截断。在这方面没有任何优势。要么你会收到支持请求“嘘,我不能使用 105 个字符的密码”,或者最终有人会发现“天啊,我只需要输入密码的前 56% 就可以工作,这是什么垃圾?! ?!?”。我认为后者实际上有一个合理的观点,而前者将极为罕见(如果有的话)。

第一个标准是安全性,然后才是可用性

我认为您可能有兴趣了解客户端 TLS 证书。