首页 > 解决方案 > SecureRandom.nextBytes() 是为 SecureRandom 实例设置初始种子的唯一方法吗?

问题描述

我已经看过很多 SecureRandom 的教程来给出以下示例:

SecureRandom random = new SecureRandom();
random.nextBytes(new byte[20]);

从文档中可以看出,当创建 SecureRandom 实例时,它还没有播种。nextBytes() 方法将为其调用默认播种。因此,我还看到以下建议:

如果使用 SHA1PRNG,请始终在创建 PRNG 的新实例后立即调用 java.security.SecureRandom.nextBytes(byte[])。

我的第一个问题是:这是必须的吗?我还可以用以下方式播种吗:

SecureRandom random = new SecureRandom();
sandom.setSeed(random.generateSeed(20));

它也是一种安全的播种方式吗?

我的第二个问题是关于重新播种。

java.security.SecureRandom 类的 setSeed(long seed) 方法用于使用给定长种子中包含的 8 个字节重新设置此随机对象的种子。给定的种子是对现有种子的补充,而不是替代。因此,保证重复调用永远不会减少随机性。

因此,这意味着一旦我立即调用 nextBytes 来调用默认播种。不管重新播种的种子是什么,它总是安全的,对吗?这是否意味着以下提供硬编码种子的代码也是安全的:

SecureRandom random = new SecureRandom();
random.nextBytes(new byte[20]);
//reseed after usage
random.setSeed(new byte[]{0x(90),0x(15)});

我也对教程https://howtodoinjava.com/java8/secure-random-number-generation/感到困惑 有一个小节 2.3:

2.3. 提供更多机会增加熵

定期创建 SecureRandom 的新实例并重新设置种子,如下所示:

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
sr.setSeed(SecureRandom.generateSeed(int))

如果种子泄露,定期重新播种可防止数据泄露。如果使用 SHA1PRNG,请始终在创建 PRNG 的新实例后立即调用 java.security.SecureRandom.nextBytes(byte[])。

这让我很困惑。这很矛盾吗?为什么它给出的代码示例没有立即调用 nextBytes 而是使用 setSeed?是重新播种吗?我想重新播种是重复播种相同的 SecureRandom 实例。但是 SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN") 会生成一个新的 secureRandom 实例,对吗?我们可以只使用一个 secureRandom 实例,但定期调用 setSeed() 来重新设置它吗?

标签: javasecurityrandomseed

解决方案


推荐阅读