bcrypt最佳工作因子

问题描述 投票:78回答:2

什么是用于密码哈希的理想bcrypt工作因素。

如果我使用10的因子,则在笔记本电脑上对密码进行哈希运算大约需要1.s。如果最终我们的站点非常繁忙,那么仅检查人们的密码就需要进行大量工作。

也许使用7的工作因子会更好,将每台笔记本电脑登录的总密码哈希工作减少到大约.01s?

您如何确定暴力安全性和运营成本之间的权衡?

bcrypt
2个回答
100
投票

[请记住,该值存储在密码$2a$(2 chars work)$(22 chars salt)(31 chars hash)中。它不是固定值。

[如果您发现负载太高,只需进行设置,以便下次他们登录时,您便可以加密出更快的计算量。同样,随着时间的流逝,您将获得更好的服务器,如果负载不是问题,则可以在登录时提高其哈希强度。

诀窍是让它与摩尔定律一起永远花到未来大致相同的时间。 数字为log2,因此每次计算机速度加倍时,请将默认数字加1。

确定暴力破解用户密码所需的时间。例如,对于某些常见的词典单词,您的帐户创建可能已经警告他们密码不正确。举例来说,如果它是1000个常用词中的一个,并且攻击者测试每个词需要0.1秒钟,那么他们将购买100个(嗯,有些词更常见...)。如果用户选择“通用词典词” + 2个数字,则超过两个小时。如果您的密码数据库遭到破坏,并且攻击者每天只能获得几百个密码,则您已花了数小时或数天的时间购买了大部分用户,以安全地更改其密码。这是为他们争取时间的问题。

http://www.postgresql.org/docs/8.3/static/pgcrypto.html有时需要破解密码供您考虑。当然,他们列出的密码是随机字母。词典单词...实际上,您不能保存密码为12345的家伙。


0
投票

短版

至少需要250毫秒进行计算的迭代次数

长版

[BCrypt于1999年首次发布时,他们列出了其实现的默认成本因素:

  • 普通用户:6
  • 超级用户:8

bcrypt成本6意味着64轮(2 6] = 64)。

他们还注意:

当然,应该重新评估人们选择的任何费用不时

  • 在1976年部署时,crypt每秒可以散列少于4个密码。 (每个密码250毫秒)
  • [1977年,在VAX-11 / 780上,每秒可评估隐窝(MD5)约3.6次。 (每个密码277毫秒)
  • 给您一种原始实现者在编写它们时所考虑的那种延迟的味道:

    • 普通用户约为250毫秒
    • 〜1秒,超级用户。
    • 但是,当然,您可以站立的时间越长越好。我见过的每个BCrypt实现都使用10作为默认成本。 my implementation使用了它。我认为现在是时候将默认费用增加到12了。

    我们已经决定要针对每个哈希不少于250ms。

    我的台式机是@ 3.50 GHz的Intel Core i7-2700K CPU。我最初在2014年1月23日对BCrypt实现进行了基准测试:

    1/23/2014  Intel Core i7-2700K CPU @ 3.50 GHz
    
    | Cost | Iterations        |    Duration |
    |------|-------------------|-------------|
    |  8   |    256 iterations |     38.2 ms | <-- minimum allowed by BCrypt
    |  9   |    512 iterations |     74.8 ms |
    | 10   |  1,024 iterations |    152.4 ms | <-- current default (BCRYPT_COST=10)
    | 11   |  2,048 iterations |    296.6 ms |
    | 12   |  4,096 iterations |    594.3 ms |
    | 13   |  8,192 iterations |  1,169.5 ms |
    | 14   | 16,384 iterations |  2,338.8 ms |
    | 15   | 32,768 iterations |  4,656.0 ms |
    | 16   | 65,536 iterations |  9,302.2 ms |
    

    enter image description here

    未来的证明

    而不是具有固定的常数,它应该是固定的[[最小。而不是使用密码哈希函数:

    String HashPassword(String password) { return BCrypt.HashPassword(password, BCRYPT_DEFAULT_COST); }

    应该是这样的:

    String HashPassword(String password) { /* Rather than using a fixed default cost, run a micro-benchmark to figure out how fast the CPU is. Use that to make sure that it takes **at least** 250ms to calculate the hash */ Int32 costFactor = this.CalculateIdealCost(); //Never use a cost lower than the default hard-coded cost if (costFactor < BCRYPT_DEFAULT_COST) costFactor = BCRYPT_DEFAULT_COST; return BCrypt.HashPassword(password, costFactor); } Int32 CalculateIdealCost() { //Benchmark using a cost of 5 (the second-lowest allowed) Int32 cost = 5; var sw = new Stopwatch(); sw.Start(); this.HashPassword("microbenchmark", cost); sw.Stop(); Double durationMS = sw.Elapsed.TotalMilliseconds; //Increasing cost by 1 would double the run time. //Keep increasing cost until the estimated duration is over 250 ms while (durationMS < 250) { cost += 1; durationMS *= 2; } return cost; }

    并且理想情况下,它将成为每个人的BCrypt库的一部分,因此,不是依靠库的用户来定期增加成本,而是定期自己增加成本。
    © www.soinside.com 2019 - 2024. All rights reserved.