random.nextBytes(bytes)如何在生成种子后生成字节

时间:2014-01-21 09:27:58

标签: java security random

我知道如果我们声明:

SecureRandom random=new SecureRandom();

初始化默认算法以生成随机数NativePRNG,其中/dev/random读取seed以生成真正的随机seed。现在我们有一个160位大小的真正随机random.nextBytes(bytes);,但我很困惑当我们调用bytes时会发生什么。它如何从seed生成/dev/random,是否会再次阅读{{1}}或其他内容。

感谢。

N.B。: 我在linux / MAC框中寻找java 7中的默认行为。

1 个答案:

答案 0 :(得分:1)

来自Java API文档:

  

许多SecureRandom实现采用伪随机的形式   数字生成器(PRNG),这意味着它们使用确定性   算法从真随机种子产生伪随机序列。   其他实现可能产生真正的随机数,还有其他实现   可以结合使用这两种技术。

因此,nextBytes(bytes)是否从/dev/random返回真正的随机字节,或者它是否返回从真随机种子生成的伪随机数取决于。第二种情况意味着使用初始随机种子,通过对SecureRandom的任何调用生成确定性但看似随机(因此,伪随机)数字序列。

Java 7允许指定可配置的PRNG源,但在Linux上,默认值为NativePRNG,在Windows SHA1PRNG上。您也可以在Linux上指定SHA1PRNG,但默认选项NativePRNG更好。 SHA1PRNG通过使用SHA1生成PRNG位和字节。在Linux(以及可能的其他机制为“NativePRNG”的Unix)上,算法从/dev/random/dev/urandom读取,只要有足够的熵可用于其中任何一个。为了完整起见,请从random上的Linux手册页:

  

来自/ dev / urandom设备的读取不会阻止等待更多   熵。结果,如果没有足够的熵   熵池,返回值理论上容易受到影响   对驱动程序使用的算法进行加密攻击。

因此,至少在Linux上,SecureRandom会有一定数量的真正随机输出,直到/dev/random由于熵不足而阻塞,然而如果您请求过多的随机位,它们最终将由底层/dev/urandom机制开始生成,这些机制可能在PRNG中使用SHA1或其他加密散列算法

最好创建一个SecureRandom,而不是自己指定任何显式种子,因为它会自行播种(默认情况下通过/dev/random/dev/urandom播放{在Linux上{1}}有一个好种子。每隔几分钟调用NativePRNG,即使是大量字节,也几乎不会在任何情况下成为问题。即使您正在使用nextBytes(bytes)并且它通过像SHA-1这样的东西从NativePRNG获取伪随机字节,它的输出仍然非常难以预测。

如果你要求千兆字节的随机性,重新种子可能是好的,要么使用/dev/urandom本身的一些输出,要么提供你自己的种子。请注意,向SecureRandom提供任何种子都应该是安全的,因为setSeed()通过将您提供的种子和之前的种子提供给SHA-1或其他加密哈希算法来内部增强当前种子。但是,最好在不提供种子的情况下创建初始SecureRandom