ngn*_*ngn 20 java security random cryptography
我们的团队正在使用SecureRandom生成密钥对列表(SecureRandom传递给KeyPairGenerator).我们无法就以下两个选项中的哪一个达成一致:
每次我们需要生成密钥对时创建一个新实例
初始化静态实例并将其用于所有密钥对
哪种方法通常更好,为什么?
补充:我的直觉是第二种选择更安全.但我唯一的论点是基于伪随机性来自当前时间戳的假设的理论攻击:某人可能看到密钥对的创建时间,猜测周围时间间隔中的时间戳,计算可能的伪随机序列,并获得关键材料.
补充:我对基于时间戳的确定性的假设是错误的.这是Random和SecureRandom之间的区别.因此,看起来答案是:在安全性方面它并不重要.
Mat*_*ugh 13
对于SecureRandom,您可能需要考虑通过如下调用偶尔重新播种(在大多数情况下使用系统熵):
mySecureRandom.setSeed(mySecureRandom.generateSeed(someInt));
Run Code Online (Sandbox Code Playgroud)
以便为潜在的攻击者提供一些不到无限的时间来发现你的密钥.
在Justice League博客上有一些关于这种考虑的好文章.
Gow*_*wri 10
与java.util.Random类不同,java.security.SecureRandom类必须在每次调用时产生非确定性输出.
这意味着什么,在以下情况下java.util.Random,如果你每次需要一个新的随机数的时间来重新创建一个实例使用相同的种子,你将基本上得到了相同的每一次的结果.然而,SecureRandom是保证不这么做-那么,创建一个实例或每次不创建一个新的不影响它生成的随机字节的随机性.
那么,从正常的良好编码实践角度来看,为什么会创建太多实例呢?
小智 6
每SecureRandom一代都是从某个熵池中播种的。根据所使用的操作系统,这可能是操作系统维护的熵池(如/dev/randomLinux),也可能是 JVM 构建的东西。在一些早期的实现中,Sun JVM 用于生成许多线程并使用它们的计时数据来创建种子。
每次调用时创建新的SecureRandom可能会导致应用程序速度减慢,因为种子的创建可能会被阻塞。最好重用静态创建的实例,但请确保在从中提取固定数量的随机字节后重新播种它。
您可能希望在实例上创建一个包装器,该包装器计算在或调用SecureRandom中提取的字节数,并在一定数量的字节之后,使用系统熵池重新播种内部实例。nextBytesgenerateSeedSecureRandom
然而,包装器方法在 Linux 上的 Java 上是不可能的,因为SecureRandom从 new 获得的实例SecureRandom()只不过是一个包装器,/dev/random并且每次调用nextBytes或generateSeed实际上都会耗尽操作系统熵池。在 Linux 和 Solaris 上,最好使用 JCE 提供程序进行SecureRandom创建。