关于Java:SecureRandom自播种

SecureRandom self-seeding

我发现了很多关于SecureRandom类的例子,如下所示:

1
2
Random random = new SecureRandom();
int randomInteger = random.nextInt();

或者像这样:

1
2
3
4
5
6
7
8
9
try
{
    Random random = SecureRandom.getInstance("SHA1PRNG");
    int randomInteger = random.nextInt();
}
catch (NoSuchAlgorithmException exception)
{
    // ...
}

或者类似的东西。

但是,SecureRandom()SecureRandom.getInstance(String)在其文档中都有此部分:

The returned SecureRandom object has not been seeded. To seed the returned object, call the setSeed method. If setSeed is not called, the first call to nextBytes will force the SecureRandom object to seed itself. This self-seeding will not occur if setSeed was previously called.

因此,在上面的例子中,Random对象在创建时从未播种。nextInt()的文档(来自Random类文档,在SecureRandom中不被重写)说明:

The method nextInt is implemented by class Random as if by:

1
2
3
public int nextInt() {
    return next(32);
}

因此,没有调用nextBytes方法,SecureRandomnext方法的文档也没有提到播种的问题。

我的问题是:上面的Random物体是否确实是种子?这些例子都是错的还是我遗漏了什么?我能安全地使用这样一个非种子随机数生成器吗?

正如评论中正确指出的那样,从源代码来看,next似乎调用了nextBytes,因此初始化种子,但是文档中没有提到这一点。


有了Sun的JRE,不播种就可以使用SecureRandom吗?不,原因是@assylias在他的评论中指出。nextInt调用nextBytes,确保SecureRandom被播种。

Java平台的另一个实现可以提供一个EDCOX1"0",它可以在没有播种的情况下使用,而仍然符合文件化的接口?对。那会很糟糕吗?哦,是的。有没有一个实施者会如此愚蠢以至于做这样的事情?大概不会。这是Java程序员需要担心的吗?不。