来自passlib documentation
因此,如果我们认为对数据库进行一次调用,则登录/注册中rounds
的最佳值是什么,并且它将 MongoDB 与非阻塞调用一起使用。 (使用Mongotor,并使用电子邮件作为_id
,因此默认情况下它是索引的,查询速度很快: 0.00299978256226 ,并且当然已使用具有 3个记录的数据库进行了测试...)
import passlib.hash
import time
hashh = passlib.hash.pbkdf2_sha512
beg1 = time.time()
password = hashh.encrypt("test", salt_size = 32, rounds = 12000)
print time.time()- beg1 # returns 0.142999887466
beg2 = time.time()
hashh.verify("test", password) # returns 0.143000125885
print time.time()- beg2
现在,如果我使用一半值(value):
password = hashh.encrypt("test", salt_size = 32, rounds = 4000) # returns 0.0720000267029
hashh.verify("test", password) # returns 0.0709998607635
在Dell XPS 15 i7 2.0 Ghz上使用 Windows 7 64位
注意:安装了bcrypt,当然,直接将其用作默认值(
rounds = 12
)确实很痛苦:hashh = passlib.hash.bcrypt
beg1 = time.time()
password = hashh.encrypt("test", rounds = 12) # returns 0.406000137329
print time.time()- beg1
beg2 = time.time()
hashh.verify("test", password) # returns 0.40499997139
print time.time()- beg2
半值:
password = hashh.encrypt("test", rounds = 12) # 0.00699996948242 wonderful?
hashh.verify("test", password) # 0.00600004196167
当使用适合生产的
pbkdf2_sha512
时,您能建议我一个很好的回合值吗? 最佳答案
(此处为passlib开发人员)
pbkdf2_sha512花费的时间与它的rounds参数(elapsed_time = rounds * native_speed
)成线性比例。使用系统数据native_speed = 12000 / .143 = 83916 iterations/second
,这意味着您需要大约83916 * .350 = 29575 rounds
才能获得〜350ms的延迟。
对于bcrypt来说,事情有些麻烦,因为它花费的时间与它的rounds参数(elapsed_time = (2 ** rounds) * native_speed
)成对数比例。使用系统数据native_speed = (2 ** 12) / .405 = 10113 iterations/second
,这意味着您需要大约log(10113 * .350, 2) = 11.79 rounds
才能获得〜350 ms的延迟。但由于BCrypt仅接受整数舍入参数,因此您需要选择rounds=11
(〜200ms)或rounds=12
(〜400ms)。
所有这些都是我希望在将来的passlib版本中解决的问题。作为一项正在进行的工作,passlib的商品 repo 当前包含一个简单的小脚本choose_rounds.py,它负责在给定的目标时间内选择正确的回合值。您可以按以下方式直接下载并运行它(运行可能需要20秒钟左右):
$ python choose_rounds.py -h
usage: python choose_rounds.py <hash_name> [<target_in_milliseconds>]
$ python choose_rounds.py pbkdf2_sha512 350
hash............: pbkdf2_sha512
speed...........: 83916 iterations/second
target time.....: 350 ms
target rounds...: 29575
$ python choose_rounds.py bcrypt 350
hash............: bcrypt
speed...........: 10113 iterations/second
target time.....: 350 ms
target rounds...: 11 (200ms -- 150ms faster than requested)
target rounds...: 12 (400ms -- 50ms slower than requested)
(编辑:增加了关于安全最小回合的响应...)
免责声明:确定安全最小值是一个令人惊讶的棘手问题-存在许多难以量化的参数,很少的真实世界数据以及一些严格无益的理论。缺乏良好的权威,我一直在自己研究这个主题。对于现成的计算,我将原始数据简化为一个简短的公式(如下所示),这通常是我使用的公式。只是要知道,其背后是几页假设和粗略的估计,这使其更像是Fermi Estimation而不是确切的答案:|
我使用GPU攻击PBKDF2-HMAC-SHA512的经验法则(2012年中)是:
days * dollars = 2**(n-31) * rounds
days
是攻击者有50/50的机会猜测密码的天数。 dollars
是攻击者的硬件预算(以$ USD为单位)。 n
是用户密码中的平均熵量(以位为单位)。 要回答您的脚本小子问题:如果平均密码具有32位熵,并且攻击者使用的是价格为$ 2000且具有良好GPU的系统,则在30000回合中,他们将需要30天(
2**(32-31)*30000/2000
)才有50/50的几率破解给定的哈希。我建议您使用这些值,直到您感到满意的舍入/天取舍为止。注意事项:
31
是关键因素,因为它编码使用特定技术级别攻击特定算法的成本估算。实际值2**-31
衡量将花费攻击者的“每轮美元天数”。为了进行比较,使用ASIC攻击PBKDF2-HMAC-SHA512具有接近46
的因素-数字越大意味着攻击者的钱更多,并且每轮安全性就越低,尽管脚本小子通常没有这种预算:)