RNGCryptoServiceProvider 的利与弊

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


更新:

根据回复,到目前为止使用 RNGCryptoServiceProvider的利弊如下:

优点

  • RNGCryptoServiceProvider是一个更强的加密随机数,这意味着它更适合于确定加密密钥等等。

缺点

  • Random更快,因为它是一个更简单的计算; 当在模拟或长时间计算中使用时,加密随机性并不重要,应该使用 Random。注意: 有关模拟的详细信息,请参阅 凯文的回答-Random不一定是足够随机的,并且您可能希望使用不同的非加密 PRNG。
27238 次浏览

一个密码学上强大的 RNG 会更慢——它需要更多的计算——而且会是光谱白色的,但不会很适合模拟或蒙特卡罗方法,因为它们 需要更多的时间,也因为它们可能不是可重复的,这对于测试来说是很好的。

一般来说,当需要一个唯一的数字(如 UUID)或作为加密的密钥,以及用于速度和模拟的确定性 PRNG 时,可以使用加密 PRNG。

是的,只有一个。正如查理马丁写的 System.Random更快。

我想补充以下信息:

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

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

System.Random不是线程安全的。

除了先前的答案之外:

System.Random应该将 从来没有用于科学和工程的模拟或数值求解,因为在这些领域存在模拟结果不准确或收敛失败的实质性负面后果。这是因为微软的实现在几个方面都是 有很多缺点,而且由于兼容性问题,他们不能(或不会)轻易地修复它。见 这篇文章

所以:

  • 如果有一个对手不知道生成的序列 ,那么使用 RNGCryptoServiceProvider或其他经过精心设计、实现和验证的加密强 RNG,并在可能的情况下理想地使用硬件随机性。< em > 否则;

  • 如果它是一个应用程序,例如一个模拟,需要良好的统计特性 ,那么使用一个精心设计和实现的非加密 PRNG,例如 梅森旋转算法。(在这些情况下,加密 RNG 也可以是 正确,但是通常太慢、太笨拙。)< em > 否则;

  • 如果数字的使用完全是微不足道的,例如决定在随机幻灯片中下一个显示的图片,那么使用 System.Random


我最近在进行蒙特卡洛模拟试验时非常明确地遇到了这个问题,该模拟试验旨在测试医疗设备不同使用模式的效果。模拟产生的结果在 相反的方向中表现平平,符合合理的预期。

有时候,当你无法解释某些事情的时候,背后总有一个原因,而这个原因可能是非常沉重的!

下面是通过越来越多的模拟批次获得的 P值的图表:

Input & output _p_‑values while using <code>System.Random</code>

红色和洋红色图显示了两个使用模型在两个输出指标的差异的统计学意义。

青色图是一个特别令人震惊的结果,因为它代表了 P-值的一个特点,随机 输入的模拟。(这只是为了确认输入没有错误。)当然,在研究中的两个使用模型之间的输入设计是相同的,所以在 输入和两个模型之间不应该有任何统计学上的显著差异。然而在这里我看到了比99.97% 更好的信心,有 曾经是这样的差异! !

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

我用一个梅森旋转算法的实现(没有其他变化)取代了 System.Random,输出立刻变得截然不同,如下所示:

Input & output _p_‑values after switching to a better PRNG

这个图表反映了在这个特定测试集中使用的参数的两个使用模型之间没有统计学上的显著差异。这是意料之中的结果。

请注意,在第一张图表中,垂直对数刻度(在 P值上)覆盖了 七十年,而在第二张图表中只有一个十年ーー这说明了虚假差异的统计显著性有多么明显!(垂直尺度表示这些差异可能是偶然出现的。)

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

碰巧的是,模拟 输入从用于内部决策的模型所使用的 RNG 流中提取,这显然导致了这些采样差异影响输入。(这实际上是一件幸运的事情,因为否则我可能没有意识到意外的结果是软件故障,而不是模拟设备的一些实际属性!)