我正在使用Java scrypt库进行密码存储。当我加密事物时N
,它需要一个r
和p
值,其文档称为“ CPU成本”,“内存成本”和“并行化成本”参数。唯一的问题是,我实际上不知道它们的具体含义,或者对他们有什么好的价值。也许它们以某种方式对应于Colin Percival原始应用程序上的-t,-m和-M开关?
有人对此有任何建议吗?该库本身列出了N = 16384,r = 8和p = 1,但是我不知道这是强还是弱还是什么。
我正在使用Java scrypt库进行密码存储。当我加密事物时N
,它需要一个r
和p
值,其文档称为“ CPU成本”,“内存成本”和“并行化成本”参数。唯一的问题是,我实际上不知道它们的具体含义,或者对他们有什么好的价值。也许它们以某种方式对应于Colin Percival原始应用程序上的-t,-m和-M开关?
有人对此有任何建议吗?该库本身列出了N = 16384,r = 8和p = 1,但是我不知道这是强还是弱还是什么。
Answers:
首先:
cpercival在他2009年的幻灯片中提到了一些
即使在今天(2012-09年),这些值也足以用于一般用途(某些WebApp的密码数据库)。当然,具体取决于应用程序。
同样,这些值(大部分)表示:
N
:一般工作系数,迭代次数。r
:用于基础哈希的块大小;微调相对内存成本。p
:并行化因子;微调相对的cpu成本。r
并且p
是为了适应潜在的问题,随着预期的CPU速度和内存大小和带宽不增加。如果CPU性能提高得更快,那么您p
应该增加,而内存技术上的突破则应该提高一个数量级r
。并且N
可以跟上每隔一段时间性能的一般翻番。
重要:所有值都会改变结果。(更新:)这就是为什么所有scrypt参数都存储在结果字符串中的原因。
这样一来,验证密码就需要250毫秒
scrypt运行所需的内存计算如下:
128字节
N_cost
××r_blockSizeFactor
对于参数你引用(N=16384
,r=8
,p=1
)
128×16384×8 = 16,777,216字节= 16 MB
选择参数时必须考虑到这一点。
Bcrypt比Scrypt(虽然比PBKDF2还要强三个数量级)“更弱”,因为它只需要4 KB的内存。您想使并行化硬件破解变得困难。例如,如果视频卡具有1.5 GB的板载内存,而您将scrypt调整为消耗1 GB的内存:
128×16384×512 = 1,073,741,824字节= 1 GB
攻击者就无法在其视频卡上并行化它。但随后,您的应用程序/电话/服务器每次计算密码时都需要使用1 GB的RAM。
它有助于我将scrypt参数视为一个矩形。哪里:
cost
(Ñ)同时增加内存使用和迭代。blockSizeFactor
([R )增加的内存使用情况。其余参数parallelization
(p)意味着您必须将整个操作进行2、3或多次:
如果您的内存比CPU多,则可以并行计算三个单独的路径-需要三倍的内存:
但是在所有实际的实现中,它都是按顺序计算的,是所需计算的三倍:
实际上,p
除了之外,没有人选择其他因素p=1
。
理想因素是什么?
上面的图形版本;您的目标是〜250ms:
笔记:
r=8
曲线中突出显示并将以上版本放大到合理区域,再次查看〜250ms幅度:
我不想采用上面提供的出色答案,但是没有人真正谈论“ r”为何具有其价值。Colin Percival的Scrypt论文提供的底层答案是,它与“内存延迟带宽积”有关。但这实际上意味着什么?
如果您正确执行Scrypt,则应该有一个大的内存块,该内存块主要位于主内存中。主内存需要花费一些时间。当块跳转循环的迭代首先从大块中选择一个元素以混合到工作缓冲区中时,它必须等待100 ns的量级才能到达第一块数据。然后,它必须请求另一个,并等待它到达。
对于r = 1,您将执行4nr Salsa20 / 8迭代和2n延迟读取的主内存读取。
这不是很好,因为这意味着攻击者可以通过构建一个减少主内存延迟的系统来比您获得优势。
但是,如果您增加r并按比例减少N,则可以实现与以前相同的内存需求并进行相同数量的计算-除了您已将某些随机访问权换成顺序访问权之外。扩展顺序访问允许CPU或库有效地预取下一个所需的数据块。虽然初始等待时间仍然存在,但后来的块减少或消除的等待时间会将初始等待时间平均到最小水平。因此,与您相比,攻击者从改进其存储技术中不会获得任何收益。
但是,随着r的增加,收益递减,这与前面提到的“内存延迟带宽积”有关。该产品表明在任何给定时间可以从主存储器到处理器传输多少字节的数据。这与高速公路的想法相同-如果从A点到B点(延迟)需要10分钟的路程,并且道路从A点(带宽)到B点(带宽介于A点和B点之间)的速度为10分钟/分钟, B包含100辆汽车。因此,最佳r与您一次可以请求多少个64字节数据块有关,以掩盖该初始请求的延迟。
这样可以提高算法的速度,允许您根据需要增加N来增加内存和计算量,或者增加p来进行更多计算。
过多增加“ r”还有其他一些问题,我没有看到太多讨论:
总结所有建议:
我在带有i5-4300(2核,4线程)的Surface Pro 3上我自己实现Scrypt的基准,使用恒定的128Nr = 16 MB和p = 230;左轴是秒,下轴是r值,误差线是+/- 1标准偏差: