密码最大长度与bcrypt,河豚

时间:2014-07-15 06:27:25

标签: encryption passwords password-encryption password-storage password-policy

我的问题来自于此 How to hash long passwords (>72 characters) with blowfish

我正在使用bcrypt(blowfish)来散列密码。所以,正如我从这个问题中发现的那样 https://security.stackexchange.com/questions/39849/does-bcrypt-have-a-maximum-password-length

它的字符数限制为72.

所以,我开始考虑限制密码的最大长度,但是在这些问题及其答案之后

https://security.stackexchange.com/questions/33470/what-technical-reasons-are-there-to-have-low-maximum-password-lengths

Why restrict the length of a password?

Should I impose a maximum length on passwords?

所有人都反对。提到的事情,比如

  • 保存存储
  • 旧的Unix系统体验
  • 与不支持长密码的旧系统交互
  • 公约(即“我们总是这样做”)
  • 简单的天真或无知。
  • 以纯文本格式存储
  • 此外,a maximum length specified on a password field should be read as a SECURITY WARNING,通过此回答 - https://stackoverflow.com/a/99724/932473

所以,我不认为我与其中一个案例相符。当然,我同意愚蠢的限制,例如最大长度10,甚至更糟,8或6,但不是30,40或更长的密码(盐渍)被认为是安全的? 从这篇文章(虽然有点旧),但它说

it can make only 71,000 guesses against Bcrypt per second

http://arstechnica.com/security/2012/12/25-gpu-cluster-cracks-every-standard-windows-password-in-6-hours/

这是8个字符的密码。因此,我想象自定义彩虹表会蛮力一个30个或更多字符密码(考虑到每个密码都有自己的盐),因为彩虹表大小呈指数增长

引用同一篇文章的评论

  

每次在密码中添加字符时,都是指数级的   增加通过蛮力破解所需的难度。对于   例如,8-char密码的密钥空间为95 ^ 8组合,而   一个20-char密码的密钥空间为95 ^ 20组合。

因此,对于一个20长度的密码与bcrypt根据那将是必要的 95 ^ 20 /(71 000 * 3600 * 24 * 365)~10年28度(如果我做对了)

qsn1:现在,在这种情况下,使用blowfish有一个意思是不要将密码最大长度限制为72,因为在任何情况下都会被截断,因此没有额外的安全性在这里获益。

qsn2:即使存在salt(每个用户都是唯一的并保存在db中),毕竟我想添加pepper(在应用程序中硬编码而不是保存在db中)到密码。我知道是否会增加一些额外的安全性,但我认为以防万一db(或db backup)只是泄露,胡椒将是有用的。 https://security.stackexchange.com/a/3289/38200 所以,为了能够添加20个字符胡椒,我需要将密码最大长度设置为50左右。我想这样:假设用户使用70个字符,在大多数情况下(如果不是全部),它将是一些短语或类似的东西,而不是产生强大的一个,所以将用户限制50最大长度并添加另一个20-22字符胡椒肯定更安全/随机更不安全。另外,假设黑客正在使用“常用短语”的彩虹表,我认为72 character common phrase被攻击的可能性高于50 character common phrase + 22 character random string。那么,这种方法是胡椒和50最大长度更好,或者我做错了,最好留72最大限制(如果qsn1没问题)?

由于

顺便说一句:

根据Owasp的说法,密码的合理最大长度为160 https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Do_not_limit_the_character_set_and_set_long_max_lengths_for_credentials

google的密码最长为100

enter image description here

Wordpress的最高限额为50

https://signup.wordpress.com/signup/

2 个答案:

答案 0 :(得分:4)

问题1:没有理由限制密码长度,BCrypt可以使用更长的密码,但只使用72个字符。你根本就没有任何优势,但从理论上讲,你会阻止密码管理员使用更长密码的人。如果您将来切换到另一个算法,限制可能会有所不同,因此没有理由限制72个字符。

问题2:您可以更好地使用其他方法,而不是胡椒化:使用服务器端密钥加密密码哈希。添加胡椒的原因是,攻击者必须获得服务器上的权限,因为没有密钥他就无法启动暴力破解哈希(SQL注入或丢弃数据库备份不会这样做)。使用加密(双向)哈希获得的优势相同。

  1. 这样你不需要为胡椒保留字符,你可以使用密码中的所有72个字符。
  2. 与胡椒相比,只要有必要,可以交换服务器端密钥。胡椒实际上成为密码的一部分,直到下次登录才能更改。
  3. 另一个discussed点是,胡椒理论上可能会干扰哈希算法。

答案 1 :(得分:-2)

除了用户提供的密码的简单散列之外,还有其他用例想要使用bcrypt安全地散列整个任意长的字符串。人们可能还希望在将密码传递给bcrypt之前对其进行加密,以获得更高的熵。

我用来绕过字符限制的一种算法是使用中间哈希。因此,我不是直接散列密码,而是使用较弱的散列机制,在bcrypt的长度限制内生成一个较短的字符串,然后使用bcrypt散列该中间字符串。中间哈希不需要强大的哈希,如bcrypt,但如果你使用高度随机化和长盐,你将最大化这种方法的有效性。我当前的中间哈希是sha512。

我用于散列密码的步骤如下:

  1. 使用/ dev / urandom等源生成长的加密安全盐。 (按用户执行此操作。如果您愿意,也可以附加应用程序范围的盐。)如果您计划将来进行密码验证,则需要存储此盐。
  2. 将salt连接到用户提供的密码。
  3. 将连接值输入sha512并捕获结果,该结果将是一个128个字符的字符串,表示十六进制数。
  4. 要添加熵并使用整个中间盐,请循环遍历整个sha512哈希,并使用十六进制数字对,将该对的值转换为ascii字符,并使用每个字符构建一个压缩的中间哈希长度为64个字符,其中有256个可能的字符。
  5. 使用您的首选参数(例如成本)将最终压缩的中间散列输入bcrypt并捕获生成的散列。
  6. 您现在拥有一个使用长密码全部值的安全哈希。