Bcrypt更长的密码

6

Bcrypt的密码长度是有限制的。我在阅读许多相关页面后,唯一无法弄清楚的是大多数网站是如何绕过此限制的。

我发现大多数网站似乎没有最大密码长度限制。也许我完全错了,但这只是我注意到的。Bcrypt似乎是这种事情中最受欢迎的库之一。

那么,所有这些网站都没有警示用户,而Bcrypt则将密码剪切为最大字符限制,并未提示用户吗?还是他们采用了某些特殊的技术以允许更长的密码?

我只是想找出如何最好地实现这一点。我希望没有最大字符限制。但与此同时,我想直接告诉用户,如果Bcrypt正在截断密码,用户应该知道。

在实践中,如何处理这个限制有什么建议吗?


1
你在哪里找到 bcrypt 有最大长度的信息? - Sylwit
1
@Sylwit 好的,我已经做了测试来证明这一点。例如,在Node.js中,我使用100个字符的密码进行注册,然后尝试仅输入前75个字符进行登录,结果返回为有效密码。此外,http://security.stackexchange.com/questions/39849/does-bcrypt-have-a-maximum-password-length - Charlie Fish
不知道。那么SHA-512密码和bcrypt呢?你会在72个字符以下吗? - Sylwit
@Sylwit,虽然这样做可能有效,但我听到很多人说这是一个非常糟糕的想法。我在这里提出了这个问题,但并没有得到太多关注:http://security.stackexchange.com/questions/131292/bypass-bcrypt-max-input。那个人说在哈希之前进行处理不是最聪明的想法,但我不确定为什么。但我在很多地方都听到过这种说法。我猜可能是因为会有更多的重叠或其他原因? - Charlie Fish
@zaph 嗯,我想知道为什么有些人会说这在实践中不是一个好主意之类的话。不过还是谢谢你的帮助!如果你愿意回答,我会给你点赞的。 - Charlie Fish
2个回答

3

我认为首先使用SHA-512没有问题。

根据NIST SP 800-63-3草案文件“数字认证指南”,密码应该接受(和使用)至少64个字符,如果它们接受更多字符,则不得截断。

实际上,NIST建议使用PBKDF与任何SHA-1、SHA-2系列、SHA-3系列一起使用,即使使用SHA1也基本上不会发生冲突,即使发生冲突也不会对密码哈希造成影响。关键在于迭代次数,以减缓攻击者的速度。

请阅读链接答案中@ilkkachu的评论。


很酷,所以在将其传递到Bcrypt之前运行SHA-512或类似的内容,然后确保Bcrypt迭代计数足够高,基本上是一种不错的身份验证策略? - Charlie Fish
它应该是一个相当不错的哈希,SHA-256或SHA-512的哈希算法都可以。 - zaph
在设计这个时,我应该考虑到哪些其他重要的提示?我知道现在我已经偏离了我的原始问题,但还有其他重要的提示或者需要注意的事项吗? - Charlie Fish
你应该尝试使用迭代次数,使得Bcrypt大约需要100毫秒左右完成,如果由于性能考虑需要更少的时间,则可以适当减少迭代次数。 - zaph

3
即使问题已经得到解答,我还想指出两件事情:
1. 用户可以输入的密码长度不应该受到限制,这是正确的。BCrypt没有问题处理超过72个字符的密码,它只会将密码截断到这个长度。因此,接受任意长度的密码,直接传递给BCrypt或使用Zaphs答案中的方案。
2. 哈希72个字符的密码足以保证非常安全。即使20个字符的密码也无法被暴力破解。
一个72个字符的密码将允许1E129种组合(不包括特殊字符)。100Giga/秒可以计算出非常快的哈希值。即使在最坏的情况下,您需要大约1E110年才能期望匹配,这大约是宇宙年龄的1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000倍!
当组合不同的哈希算法时,请注意:
如果正确执行,这可以增加熵。如果输入的密码超过72个字符(这很少见),且密码不是随机的(如果有人注意使用这样长的密码,则不太可能出现这种情况)。有很多“如果”。
但是也有陷阱:
1. 如果您使用SHA-512的二进制输出,则可能会遇到\0字符,这可能会导致不安全的哈希值,请参见此article。 2. 如果您使用SHA的十六进制/ base64表示形式,则限制了72个位置的可能字符。

似乎将密码截断为72个字符并不是最好的选择。似乎首先通过SHA或某种哈希算法进行处理似乎是最佳解决方案。 - Charlie Fish
@zaph - 抱歉我没有理解你的回答,可能部分原因是语言(英语不是我的母语)。您不同意需要警告有关预哈希陷阱的内容吗?我认为我们都在努力使代码更安全,那么为什么要投反对票呢?我愿意听取理由,并删除了任何关于MD5的提示,因为它与我的答案无关,陈述仍然完全相同。 - martinstoeckli
抱歉关于“草人”的问题:“一个虚假的论点被设置为被击败”,没有解决主要问题。是的,需要编写正确的代码,包括处理数据(0x00字节)和编码,这是标准编程。随着MD5的消失,重要问题是接受密码并截断它,这不是当前最佳实践,而是限制允许的长度,这样用户就可以掌控而不会受到意外惊吓。 - zaph
@zaph - 同意没有限制会更好,但BCrypt确实有这个72个字符的限制(字节而不是位)。正如你所说的32个字节的熵已经足够了(因此BCrypt的72个字节也足够了),但预哈希不会改变原始密码的熵,它只能将更多的原始熵带入到接受的72个字符中。这仅适用于使用小字符集的非常长的密码。而且因为正确地执行这个过程并不容易,所以我认为写下这个警告是一个好主意。 - martinstoeckli
它只能将更多的原始熵带入Bcrypt的72个字符限制中,这就是重点。两种最佳实践是:(1)将允许的输入限制在72个字符以内(NIST推荐的最小字符数为64个字符以上),或者(2)使用整个用户输入。不能因为“正确地执行不是轻松的事情”而使用差劲的安全性。选项1不会增加复杂性。或者使用NIST推荐的PBKDF1。请考虑到用户处于由于密码处理不当而面临风险,他们期望并值得获得良好和适当的安全性。 - zaph
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接