我想允许提交任何大小的密码。我目前使用 bcrypt 作为密码的密钥派生函数,但是我意识到它的最大输入长度为 72。
因此,我想在将密码传递给 bcrypt 之前对其进行 sha512 处理,允许注册任何大小的密码,因为我的理解是 sha512 输出 64 个字节。
这是好的做法吗?我听说混合和匹配哈希或“创建自己的加密”是不好的做法,但这似乎是硬限制的可行解决方法。
谢谢。
我想允许提交任何大小的密码。我目前使用 bcrypt 作为密码的密钥派生函数,但是我意识到它的最大输入长度为 72。
因此,我想在将密码传递给 bcrypt 之前对其进行 sha512 处理,允许注册任何大小的密码,因为我的理解是 sha512 输出 64 个字节。
这是好的做法吗?我听说混合和匹配哈希或“创建自己的加密”是不好的做法,但这似乎是硬限制的可行解决方法。
谢谢。
在将密码推入 bcrypt 之前,使用一个体面、安全的哈希函数对密码进行哈希处理是一种合理且安全的方式,可以保持 bcrypt 的所有优点,并且还支持任意大小的密码。
您仍然需要对一些实际细节保持谨慎。特别是,许多 bcrypt 实现期望密码,即字符序列,以值 0x00 的第一个字节结束。SHA-512 的输出是二进制的,因此可能包含一些值为 0x00 的字节。例如,所有密码的 1/256 将产生一个以 0x00 字节开头的哈希值,基于字符串的 bcrypt 实例将理解为等效于空密码。情况不妙...
解决方案是使用确定性的字节到字符编码,例如Base64。由于这意味着一些大小扩展,SHA-512 将不再足够(Base64 将 64 个字节转换为 88 个字符,超过 bcrypt 的 72 个限制)。因此,使用 SHA-256:256 位输出(32 字节)将由 Base64 编码为 44 个字符,使用 bcrypt 就可以了。
(无论如何,SHA-512 的 512 位输出大小完全是矫枉过正。SHA-256 已经足够好了。)
据我所知,使用加密散列函数对用户输入进行预散列,然后使用密码散列函数对结果进行散列是可以接受的。
Mozilla 建议使用 hmac+bcrypt,如果您为 HMAC 选择 SHA512 应该没问题。(我相信 SHA512 和 AES256 是一样的矫枉过正,所以你可以通过使用 SHA256 来节省一些 CPU 周期而不牺牲安全性)
Makwa 密码散列函数是Thomas Pornin密码散列竞赛的候选者,实际上支持前散列和后散列。
这不会削弱您的密码,也不会增加额外的安全性。即使在截断更长的密码之后,熵仍然足够高。实际上,也经常用于散列密码的 PBKDF2 在密码的派生密钥超过块大小时会执行类似的操作。
SHA-256 绰绰有余。
它解决了输入大小的 72 字节限制,并避免了长度溢出错误(超过 255 个字符的长度将输入减少到 0 并再次增加),这两个实现已知并且自 2014 年(OpenBSD)和 2020 年(NodeJS)修补以来.
即使您的密码熵高于 256 位,bcrypt 输出也是 184 位。尽管这两种熵级别的攻击都不可行,但 184 位的工作量比 256 位或更高的要少。