SecureRandom:init 一次还是每次需要它?

2022-09-01 09:45:31

我们的团队正在使用 SecureRandom 生成密钥对列表(SecureRandom 被传递到 KeyPairGenerator)。我们无法就使用以下两个选项中的哪一个达成一致:

  1. 每次我们需要生成密钥对时创建一个新实例

  2. 初始化静态实例并将其用于所有密钥对

哪种方法通常更好,为什么

补充:我的直觉是,第二种选择更安全。但我唯一的论点是基于伪随机性是从当前时间戳派生的假设的理论攻击:有人可能会看到密钥对的创建时间,猜测周围时间间隔中的时间戳,计算可能的伪随机序列,并获得密钥材料。

补充:我对基于时间戳的决定论的假设是错误的。这就是 Random 和 SecureRandom 之间的区别。所以,看起来答案是:就安全性而言,这并不重要。


答案 1

与类不同,该类必须在每次调用时生成非确定性输出。java.util.Randomjava.security.SecureRandom

这意味着,在 的情况下,如果您每次需要一个新的随机数时都使用相同的种子重新创建一个实例,那么您每次基本上都会得到相同的结果。但是,保证不会这样做 - 因此,每次创建单个实例或创建新实例不会影响它生成的随机字节的随机性。java.util.RandomSecureRandom

那么,从普通的良好编码实践的角度来看,为什么要创建太多的实例呢?


答案 2

对于 SecureRandom,您需要考虑偶尔通过如下调用来重新设定种子(在大多数情况下使用系统熵):

mySecureRandom.setSeed(mySecureRandom.generateSeed(someInt));

以便为潜在攻击者提供少于无限时间来发现您的密钥。

正义联盟博客上有一些关于这个考虑的精彩文章。