什么是最佳的scrypt工作因素?

时间:2012-06-20 18:57:07

标签: java cryptography scrypt

我正在使用Java scrypt library进行密码存储。当我加密事物时,它需要Nrp值,其文档称为“CPU成本”,“内存成本”和“并行化成本”参数。唯一的问题是,我实际上并不知道它们的具体含义,或者对它们有什么好的价值;也许它们以某种方式对应Colin Percival's original app上的-t,-m和-M开关?

有人对此有任何建议吗?图书馆本身列出N = 16384,r = 8和p = 1,但我不知道这是强还是弱或者是什么。

3 个答案:

答案 0 :(得分:65)

首先:

cpercival 提到in his slides from 2009周围的事情

  • (N = 2 ^ 14,r = 8,p = 1)< 100毫秒(交互式使用)和
  • (N = 2 ^ 20,r = 8,p = 1)< 5s(敏感存储)。

即使在今天(2012-09),这些值恰好足以满足一般用途(某些WebApp的密码-db)。当然,细节取决于应用程序。

此外,这些值(大多数)意味着:

  • N:一般工作因素,迭代次数。
  • r:用于底层哈希的blocksize;微调相对记忆费用。
  • p:并行化因素;微调相对cpu-cost。

rp旨在解决CPU速度和内存大小和带宽未按预期增加的潜在问题。如果CPU性能增加得更快,那么增加p,相反,内存技术的突破提供了一个数量级的改进,你增加r。并且N可以跟上每个某个时间段的性能一般加倍。

重要提示:所有值都会更改结果。 (更新:)这就是为什么所有scrypt参数都存储在结果字符串中的原因。

答案 1 :(得分:53)

scrypt操作所需的内存计算如下:

  

128字节×N_cost×r_blockSizeFactor

表示您引用的参数(N=16384r=8p=1

  

128×16384×8 = 16,777,216字节= 16 MB

选择参数时必须考虑到这一点。

Bcrypt “弱”比Scrypt(虽然仍然是three orders of magnitude stronger than PBKDF2)因为它只需要4 KB的内存。您希望难以并行化硬件中的破解。例如,如果视频卡具有1.5 GB的板载内存,并且您调整了scrypt以消耗1 GB的内存:

  

128×16384×512 = 1,073,741,824字节= 1 GB

然后攻击者无法在其视频卡上并行化。但是,每当他们计算密码时,您的应用程序/电话/服务器就需要使用1 GB的RAM。

这有助于我将scrypt参数视为矩形。其中:

  • 宽度是所需的内存量(128 * N * r)
  • 高度是执行的迭代次数
  • ,结果区域是整体硬度

enter image description here

  • cost N )会增加内存使用量迭代次数
  • blockSizeFactor r )会增加内存使用量

剩下的参数parallelization p )意味着您必须完成2,3或更多次的整个事情:

enter image description here

如果你的内存多于CPU,你可以并行计算三个独立的路径 - 需要三倍的内存:

enter image description here

但是在所有实际实现中,它是按顺序计算的,需要的计算增加三倍:

enter image description here

实际上,除了p之外,没有人选择p=1因子。

理想因素是什么?

  • 尽可能多的RAM
  • 尽可能多的时间!

奖金表

上述图形版本:

enter image description here

注意:

  • 垂直轴是对数刻度
  • 成本系数(水平)本身是log(迭代= 2 CostFactor
  • r=8曲线
  • 中突出显示

将上面的版本放大到合理的区域:

enter image description here

答案 2 :(得分:11)

我不想踩到上面提供的优秀答案,但没有人真正谈论为什么" r"有它的价值。 Colin Percival的Scrypt论文提供的低级答案是它与内存延迟带宽产品有关"。但这究竟意味着什么?

如果你正确地做Scrypt,你应该有一个大的内存块,它主要位于主内存中。主存储器需要时间来拉动。当块跳转循环的迭代首先从大块中选择一个元素以混合到工作缓冲区时,它必须等待100ns的量级才能到达第一块数据。然后它必须请求另一个,并等待它到达。

对于r = 1,您将从主内存执行4nr Salsa20 / 8次迭代 2n延迟时间读取。

这并不好,因为这意味着攻击者可以通过构建一个减少主内存延迟的系统来获得优势。

但是如果你增加r并按比例减少N,你就可以达到相同的内存要求并进行与以前相同的计算次数 - 除了你已经进行了一些随机访问以进行顺序访问。扩展顺序访问允许CPU或库有效地预取下一个所需的数据块。虽然初始延迟仍然存在,但后续块的延迟减少或消除将初始延迟平均到最小水平。因此,攻击者从改善他们的记忆技术中获得的收益很少。

然而,随着r的增加,有一个收益递减点,这与内存延迟 - 带宽产品"有关。之前提到的。该产品表示在任何给定时间可以从主存储器传输到处理器的数据字节数。它与高速公路的想法相同 - 如果从A点到B点(延迟)需要10分钟,并且道路从A点(带宽)向道路提供10辆车/分钟到B点A点和B点之间包含100辆汽车。因此,最优r与您可以一次请求多少64字节数据块有关,以便掩盖初始请求的延迟。

这提高了算法的速度,允许您根据需要增加N以获得更多内存和计算,或增加p以进行更多计算。

还有其他一些问题需要增加" r"太多了,我还没有见过多少讨论:

  1. 在减少N的同时增加r会减少内存周围的伪随机跳转次数。顺序访问更容易优化,并且可以为攻击者提供一个窗口。正如Colin Percival在Twitter上向我指出的那样,较大的r可能允许攻击者使用成本更低,速度更慢的存储技术,大大降低了成本(https://twitter.com/cperciva/status/661373931870228480)。
  2. 工作缓冲区的大小为1024r位,因此最终输入PBKDF2以生成Scrypt输出密钥的最终产品数量为2 ^ 1024r。大存储块周围的跳跃的排列(可能序列)的数量是2 ^ NlogN。这意味着内存跳跃循环有2 ^ NlogN个可能的产品。如果1024r> NlogN,似乎表明工作缓冲区混合不足。虽然我不确定地知道这一点,并且希望看到证明或反证,但可能可以在工作缓冲区的结果和序列之间找到相关性跳跃,这可以让攻击者有机会减少他们的内存需求,而不会大大增加计算成本。同样,这是一个基于数字的观察 - 可能每一轮中的所有事情都是如此混合,这不是一个问题。 r = 8远低于标准N = 2 ^ 14的潜在阈值 - 对于N = 2 ^ 14,该阈值将为r = 224。
  3. 总结所有建议:

    1. 选择r足够大以平均效果 设备上的内存延迟,不再有。请记住 Colin Percival建议,r = 8,似乎保持公平 广泛用于记忆技术,这显然没有 8年来变化很大; 16可能会好一点。
    2. 决定每个线程要使用多大的内存, 请记住,这也会影响计算时间,并设置N. 相应地。
    3. 将p任意增加到您的使用量可以容忍的范围(注意: 在我的系统上并使用我自己的实现,p = 250(4 线程)N = 16384且r = 8需要~5秒),并启用 如果你可以处理增加的内存成本,则进行线程化。
    4. 调整时,首选大N和内存块大小增加p和 计算时间。 Scrypt的主要优势来自其庞大的优势 内存块大小。
    5. 我在Surface Pro 3上使用i5-4300(2核,4个线程)实现Scrypt的基准测试,使用常数128Nr = 16 MB和p = 230;左轴为秒,底轴为r值,误差棒为+/- 1标准差:

      Scrypt r values vs. p with constant large block size