RNGCryptoServiceProvider的优缺点


71

什么是使用的利弊System.Security.Cryptography.RNGCryptoServiceProviderVS System.Random。我知道这RNGCryptoServiceProvider是“更加随机的”,即对于黑客来说更难以预测。还有其他优点或缺点吗?


更新:

根据回应,以下是目前使用的利弊RNGCryptoServiceProvider

优点

  • RNGCryptoServiceProvider 是一个更强的密码随机数,这意味着确定加密密钥等会更好。

缺点

  • Random更快,因为它是一个更简单的计算;当用于不要求加密随机性的模拟或长时间计算时,应使用此方法。注意:有关模拟的详细信息,请参见Kevin的答案-Random不一定足够随机,您可能要使用其他非加密PRNG。

Answers:


54

加密性强的RNG会慢---它需要更多的计算---而将频谱白色的,但不会也适用于模拟或蒙特卡罗方法,一方面是因为他们需要更多的时间,因为他们可能不可重复,非常适合测试。

通常,当您想要唯一的数字(例如UUID)或要用作加密的密钥,而要确定性的PRNG来进行速度和仿真时,则希望使用加密的PRNG。


1
例如Blum Blum Shub与Mersenne Twister。创建BBS时要牢记强大的密码学证明,并且出于非加密目的,要使其接近随机数,它的速度太慢且占用大量资源。
2009年

重新测试时,您始终可以在测试时使用Random并将实现更改为在生产中使用RNGCryptoServiceProvider,不是吗?
配置器

可以,但是强大的PRNG仍然不适合像Monte Carlo这样的用途。在生产用途中,重复性和速度也是理想的。
查理·马丁

“光谱白色”是什么意思?
罗伯特·麦克莱恩

2
@CharlieMartin“功率谱是平坦的,没有更可能的数字组”。请问不是事实,频谱平坦意味着该号码的一些团体更有可能出现?在RNGCryptoServiceProvider中,每个位大约有50%的机会被设置,这意味着设置位的一半左右的数字将是最受欢迎的,并且仅设置几个位(或设置了所有位的值)的数字将是最受欢迎的。非常不可能。
josh poley

12

System.Random 不是线程安全的。


好点子。您可以参阅blogs.msdn.com/pfxteam/archive/2009/02/19/9434171.aspx进行进一步的讨论。
配置器

4
现在,我考虑了一下,RNGCryptoServiceProvider也不是!
配置器

10
MSDN似乎说RNGCryptoServiceProvider是线程安全的(msdn.microsoft.com/en-us/library/…)。
Scott Lawrence 2010年

4
除了开玩笑,它可能会破坏自身并返回零(stackoverflow.com/a/11109361/155892)。(dilbert.com/strips/comic/2001-10-25
马克Sowul

9

是的,只有一个。正如查理·马丁(Charlie Martin)所写的那样System.Random,速度更快。

我想添加以下信息:

RNGCryptoServiceProvider是符合安全标准的随机数生成器的默认实现。如果出于安全目的需要随机变量,则必须使用此类或等效类,但不要使用System.Random,因为它具有很高的可预测性。

对于所有其他用途System.Random,我们欢迎,和等效类的更高性能。


我可以使用rngcryptoserviceprovider作为不同应用程序使用的webapi的身份验证令牌吗?

3

除了先前的答案:

System.Random应该永远不要在模拟或科学与工程数值求解器,哪里有不准确的仿真结果或者收敛失败实质性的负面影响使用。这是因为Microsoft的实现在多个方面都存在严重缺陷,并且由于兼容性问题,他们无法(或不会)轻松地对其进行修复。看到 这篇文章

所以:

  • 如果有一个对手不知道所生成的序列,则使用RNGCryptoServiceProvider或另一种经过精心设计,实施和验证的具有加密功能的强RNG,并在可能的情况下最好使用硬件随机性。 除此以外;

  • 如果是诸如模拟之类的应用程序需要良好的统计属性,则请使用经过精心设计和实现的非加密PRNG,例如Mersenne Twister。(A加密RNG也将是正确的在这些情况下,但往往过于缓慢和笨拙。) 否则,

  • 当数字的使用完全无关紧要时,例如确定随机幻灯片中接下来要显示的图片,然后使用System.Random


我最近在进行旨在测试医疗设备不同使用模式的效果的蒙特卡洛仿真时非常切实地遇到了这个问题。模拟产生的结果合理预期的方向略有相反

有时,当您无法解释某些内容时,背后有一个原因,而这个原因可能会非常繁重!

这是在越来越多的模拟批次中获得的p值的图:

使用<code> System.Random </ code>时输入和输出_p_values

红色和品红色图表显示了所研究的两个输出指标中两个使用模型之间差异的统计显着性。

青色图是一个特别令人震惊的结果,因为它表示模拟的随机输入特征的p值。(这只是为了确认输入没有错误而作图。)当然,通过设计,在所研究的两个使用模型之间的输入是相同的,因此,在两个模型的输入之间应该没有任何统计学上的显着差异。。然而,在这里,我比99.97%的置信看到更好的,有 这样的差别!

最初我以为我的代码有问题,但是一切都检查了。(特别是我确认线程没有共享System.Random 实例。)当重复测试发现此意外结果高度一致时,我开始怀疑 System.Random

我将其替换System.Random为Mersenne Twister的实现-无需进行其他更改,立即使输出变得截然不同,如下所示:

切换到更好的PRNG后输入和输出_p_值

此图反映了在此特定测试集中使用的参数的两种用法模型之间在统计上没有显着差异。这是预期的结果。

请注意,在第一个图表中,垂直对数刻度(在p值上)涵盖了七个十年,而第二个图表中只有一个十年-表明了虚假差异的统计显着性!(垂直刻度表示差异可能是偶然产生的。)

我怀疑正在发生的事情是System.Random在一个相当短的生成器周期上存在一些相关性,并且两个被测模型之间的内部随机抽样的不同模式(对的调用次数大不相同 Random.Next)导致它们以不同的方式影响两个模型。 。

碰巧的是,模拟输入来自与模型用于内部决策的RNG流相同的RNG流,这显然导致了这些采样差异会影响输入。(这实际上是幸运的事情,因为否则我可能没有意识到意外的结果是软件故障,而不是被仿真设备的某些真实属性!)


有趣。我不知道统计差异。谢谢!
配置器
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.