【问题标题】:Repetitive usage of Java's SecureRandom重复使用 Java 的 SecureRandom
【发布时间】:2015-02-22 20:55:11
【问题描述】:

我对@9​​87654322@ 的用法有点困惑。我需要在循环中生成 n secure 随机数。每一代都使用相同的 SecureRandom 实例是否安全?以下解决方案在加密强度方面有什么区别吗?

1) 没有种子的单实例

SecureRandom sr = new SecureRandom();
for(int i = 0; i < n; ++i) sr.nextInt();

2) 每一代的新实例

for(int i = 0; i < n; ++i) new SecureRandom().nextInt();

3) 带种子的单个实例

SecureRandom sr = new SecureRandom()
for(int i = 0; i < n; ++i) {
    byte[] seed = sr.generateSeed(32);
    sr.setSeed(seed);
    sr.nextInt();
}

【问题讨论】:

  • “我需要在一个循环中生成 n 个随机数”——第一个问题是,你需要随机数,还是安全随机数。如果是前者,那么您不需要SecureRandom。您可以使用Linear Congruential Generator。 LCG 适用于模拟,您需要从均匀分布中快速获得数字。

标签: java security random cryptography


【解决方案1】:

也许与直觉相反,第三个几乎可以肯定是最弱的,在循环迭代中重新播种是一个糟糕的主意。第二个很糟糕,但没那么糟糕,因为SecureRandom() 包含一个strong 默认播种策略。正如所问的,第一个几乎可以肯定是最安全的,因为它使熵周期最大化。出于这个原因,我建议您将其提取到类级别的常量中。

private static final Random RANDOM = new SecureRandom();
// ...
// your method,
for (int i = 0; i < n; ++i) { 
    int num = RANDOM.nextInt();
}

【讨论】:

  • “也许与直觉相反,第三个几乎可以肯定是最弱的,在循环迭代上重新播种是一个糟糕的主意......” - 有几篇论文可能不同意与你。论文建议在要求生成器生成位之前为实例重新播种生成器。
  • “第二个很糟糕,但没有那么糟糕,因为 SecureRandom() 包含一个强大的默认播种策略” - 反例证明:Android SecureRandom。始终在使用前播种生成器。不要依赖别人。
  • @jww 我认为它仍然不如选项 3 糟糕。
【解决方案2】:

我建议你应该阅读这个有趣的article

一般来说,不需要创建多个 SecureRandom() 实例,正如@ElliottFrisch 所说,static final 是最合适的解决方案。

但是,如果您将 SecureRandom 用于大量随机输出序列,则应定期对其重新设置种子,以免恶意软件确定种子并预测所有未来输出。

【讨论】:

    猜你喜欢
    • 2015-01-26
    • 2023-03-13
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2017-06-30
    • 2012-08-28
    相关资源
    最近更新 更多