重复使用Java';安全随机

重复使用Java';安全随机,java,security,random,cryptography,Java,Security,Random,Cryptography,我对SecureRandom的用法有点困惑。我需要在一个循环中生成nsecure随机数。为每一代使用相同的SecureRandom实例是否安全?以下解决方案在加密强度方面是否存在任何差异 1) 无种子的单实例 SecureRandom sr = new SecureRandom(); for(int i = 0; i < n; ++i) sr.nextInt(); SecureRandom sr=new SecureRandom(); 对于(int i=0;i

我对
SecureRandom
的用法有点困惑。我需要在一个循环中生成nsecure随机数。为每一代使用相同的SecureRandom实例是否安全?以下解决方案在加密强度方面是否存在任何差异

1) 无种子的单实例

SecureRandom sr = new SecureRandom();
for(int i = 0; i < n; ++i) sr.nextInt();
SecureRandom sr=new SecureRandom();
对于(int i=0;i
2) 每一代的新实例

for(int i = 0; i < n; ++i) new SecureRandom().nextInt();
for(int i=0;i
3) 带种子的单实例

SecureRandom sr = new SecureRandom()
for(int i = 0; i < n; ++i) {
    byte[] seed = sr.generateSeed(32);
    sr.setSeed(seed);
    sr.nextInt();
}
SecureRandom sr=new SecureRandom()
对于(int i=0;i
也许与直觉相反,第三个几乎肯定是最薄弱的,在循环迭代中重新播种是一个糟糕的想法。第二个是坏的,但不那么坏,因为
SecureRandom()
包含一个强大的默认种子策略。正如所问,第一个几乎肯定是最安全的,因为它最大化了熵周期。因此,我建议您将其提取为类级别常量

private static final Random RANDOM = new SecureRandom();
// ...
// your method,
for (int i = 0; i < n; ++i) { 
    int num = RANDOM.nextInt();
}
private static final Random=new SecureRandom();
// ...
//你的方法,,
对于(int i=0;i
我建议你读这篇有趣的文章

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


但是,如果您将SecureRandom用于大量随机输出,则应定期重新设置种子,以防恶意软件确定种子,从而预测所有未来的输出。

“我需要在循环中生成n个随机数”-第一个问题是,您需要随机数还是安全随机数。如果是前者,则不需要
SecureRandom
。你可以用一个。LCG适用于模拟,在模拟中,你需要从均匀分布中快速获得数字。“也许与直觉相反,第三个几乎肯定是最弱的,在循环迭代中重新播种是一个糟糕的想法…”有几篇论文可能不同意你的观点。论文建议在要求生成器生成位之前将生成器重新播种到实例中。“第二个不好,但不那么坏,因为SecureRandom()包含一个强大的默认播种策略”-反例证明:。在使用发电机之前,务必对其进行播种。不要依赖他人。@jww我认为这比选项3更糟糕。