【问题标题】:python passlib: what is the best value for "rounds"python passlib:“回合”的最佳价值是什么
【发布时间】:2012-11-12 19:09:21
【问题描述】:

来自passlib documentation

对于大多数面向公众的服务,在用户开始生气之前,您通常需要 250 毫秒到 400 毫秒的时间进行登录。

那么,如果我们认为登录尝试一次调用数据库,那么 登录/注册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

现在如果我使用半值:

password = hashh.encrypt("test", salt_size = 32, rounds = 4000) # returns 0.0720000267029
hashh.verify("test", password) # returns 0.0709998607635

我在戴尔 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 时,您能否建议我一个适合生产的良好回合值?

【问题讨论】:

    标签: python encryption pbkdf2


    【解决方案1】:

    (此处为 passlib 开发者)

    pbkdf2_sha512 花费的时间与它的 rounds 参数 (elapsed_time = rounds * native_speed) 成线性比例。使用您系统的数据 native_speed = 12000 / .143 = 83916 iterations/second,这意味着您需要大约 83916 * .350 = 29575 rounds 才能获得约 350 毫秒的延迟。

    对于 bcrypt 来说,事情有点复杂,因为它所花费的时间与它的 rounds 参数 (elapsed_time = (2 ** rounds) * native_speed) 成对数比例。使用您系统的数据native_speed = (2 ** 12) / .405 = 10113 iterations/second,这意味着您需要大约log(10113 * .350, 2) = 11.79 rounds 才能获得约350 毫秒的延迟。但由于 BCrypt 只接受整数轮参数,所以你需要选择 rounds=11 (~200ms) 或 rounds=12 (~400ms)。


    所有这些都是我希望在 passlib 的未来版本中解决的问题。作为一项正在进行的工作,passlib 的 mercurial 存储库当前包含一个简单的小脚本 choose_rounds.py,它负责为给定的目标时间选择正确的轮数值。可以直接下载运行如下(运行可能需要20s左右):

    $ 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 是攻击者的硬件预算(美元)。
    • n 是用户密码的平均熵值(以比特为单位)。

    回答你的脚本小子问题:如果一个平均密码有 32 位熵,并且攻击者有一个 2000 美元的系统和一个好的 GPU,那么在 30000 轮时他们将需要 30 天( 2**(32-31)*30000/2000) 有 50/50 的机会破解给定的哈希。我建议您使用这些值,直到您达到您满意的回合/天折衷。

    注意事项:

    • 字典攻击的成功率不是线性的,它更像是“长尾”情况,所以将 50/50 标记视为更多的半衰期。

    • 31 是关键因素,因为它编码了使用特定技术级别攻击特定算法的成本估计。实际值2**-31 衡量攻击者将花费的“每轮美元天数”。相比之下,使用ASIC 攻击 PBKDF2-HMAC-SHA512 的系数更接近于46 - 更大的数字意味着攻击者的成本更高,并且每轮的安全性更低,尽管脚本小子通常不会有那种预算:)

    【讨论】:

    • 首先:感谢您提供这个漂亮的库,然后:安全性如何,安全应用程序的最佳价值(最小值)是多少(不是 NASA 安全应用程序,只是一个避免脚本小子的简单应用程序)?
    • 很高兴它有用!回复:安全最低限度 - 我试图将我的回复编辑到 500 个字符,但放弃并将其添加为我上面答案的附录 - 我希望它不会太长。它本质上是我计划添加到 passlib 手册中的一些文本的清理版本(最终)。
    • 哇!谢谢!所有这些信息都很有帮助,再次感谢您所做的一切:)
    • 在“仔细”阅读了答案之后,我认为这对于想要拥有安全背景的程序员来说将是一个很好的参考。再次感谢你:)
    • 你能让choose_rounds.py兼容Python3吗? :)
    猜你喜欢
    • 2011-03-02
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多