带有NativePRNG和SHA1PRNG的SecureRandom

我需要生成加密强大的随机数和字节数组。 为此,我使用的是Java的SecureRandom类。 但我不确定在加密强度方面选择哪种PRNG算法。

以下哪个实例会产生更难以预测的数字? 或者他们是平等的?

 SecureRandom nativePrng = SecureRandom.getInstance("NativePRNG") SecureRandom sha1Prng = SecureRandom.getInstance("SHA1PRNG") 

此外,我们能够使用“SUN”提供程序生成这些实例(例如SecureRandom.getInstance("SHA1PRNG", "SUN") )。 这会有所作为吗?

提前致谢。

TL; DR:当你不确定时使用new SecureRandom()让系统搞清楚。 可能使用SecureRandom.getInstanceStrong()进行长期密钥生成。

不要指望随机数生成器在运行时应用程序中生成特定的输出序列。


对于随机数生成器,总是很难说哪个是最好的。 Linux和大多数Unix都有一个经过深思熟虑的随机数生成器,因此使用/dev/random/dev/urandom (即"NativePRNG"并没有什么坏处。 使用/dev/random是它会阻塞,直到有足够的熵可用。 所以除非你对密钥生成有一些特殊要求,否则我会反对它。


"SHA1PRNG"使用散列函数和计数器以及种子。 该算法相对简单,但尚未得到很好的描述。 通常认为它是安全的。 由于它只是在启动期间来自其中一个系统生成器的种子,因此需要较少的内核调用,因此可能会减少资源密集度 – 在我的系统上运行速度比"NativePRNG" (配置为使用/dev/urandom速度快9倍)快9倍。 /dev/urandom )。 两者似乎只对我的双核Ubuntu笔记本电脑的一个核心征税(一次,它经常从一个核心切换到另一个核心,这可能是内核调度,这是应该责备的)。 如果您需要高性能,请选择此项,特别是如果/dev/urandom设备在特定系统配置上运行缓慢。

请注意,已"SHA1PRNG"的Apache Harmony实现中的"SHA1PRNG"与SUN提供程序中的"SHA1PRNG"不同(Oracle在标准Java SE实现中使用)。 雅加达的版本也用于旧版本的Android。 虽然我无法进行全面审查,但它看起来并不十分安全。

编辑:我并没有错误, SHA1PRNG已被certificate不是伪随机版本<4.2.2及更多。


一般来说,要求特定的提供商也不是一个好主意。 指定提供商可能会损害互操作性; 并非每个Java运行时都可以访问SUN提供程序 – 例如Android肯定没有。 它还使您的应用程序在运行时不太灵活,即您不能将提供程序放在列表中更高的位置并使用它。

因此,如果您依赖其提供的某项function,则仅指明提供商。 例如,如果您具有生成randoms的特定硬件设备,或者已获得FIPS认证的加密库,则可能需要指定提供程序。 如果必须指定提供程序,那么为算法/提供程序提供应用程序的配置选项可能是个好主意。

此Android开发人员安全博客中也提供了不指定提供程序的想法。


所以尽量不要选择任何特定的随机发生器。 相反,只需转到空参数构造函数: new SecureRandom()并让系统选择最佳随机数生成器。 如果您对长期密钥生成有任何特定要求,则可以在Java 8中使用新的可配置SecureRandom.getInstanceStrong()

不要缓存SecureRandom实例,只是让它们最初自己播种并让VM处理它们。 我没有看到明显的操作差异。


什么时候不使用SecureRandom

作为一般性警告,我强烈建议不要将随机数生成器用于除随机数生成之外的任何其他内容。 即使您可以自己播种,即使您选择了Sun的SHA1PRNG, 也不要指望能够从随机数生成器中提取相同的随机数序列 。 因此, 不要将它用于密码的密钥派生,仅举一个例子。

如果确实需要重复序列,则使用流密码并使用密钥和IV的种子信息。 加密由零组成的明文以检索伪随机值的密钥流。 或者,您可以使用可扩展输出function(XOF),例如SHAKE128或SHAKE256(如果可用)。

显然,对于不需要安全性的超高速操作,请不要使用SecureRandom ; 它不会像其他确定性随机数生成器那样快,例如那些基于Mersenne Twister算法的生成器。

来自参考。 这里 :

Solaris / Linux的本机PRNG实现。 它与/ dev / random和/ dev / urandom交互,因此仅在存在这些文件时才可用。 否则,使用SHA1PRNG而不是此类。

SUN提供程序可能用作默认值(主要取决于提供程序的顺序)。