在Java中的SecureRandom安全的种子(SecureRandom safe seed in

2019-06-27 18:20发布

这是一段代码安全吗?

 SecureRandom randomizer = new SecureRandom(String.valueOf(new Date().getTime()).getBytes());

这是实例正道安全随机的种子?

Answer 1:

不,你应该避免SecureRandom(byte[])构造函数。 它既是不安全的,不便于携带。

这是不可移植的,因为它表现不同的Windows与其他操作系统。

在大多数操作系统中,默认的算法是“NativePRNG”,它从OS(通常获得的随机数据"/dev/random" ),并忽略你提供种子。

在Windows中,默认的算法是“SHA1PRNG”,这与计数器结合你的后裔和计算结果的哈希值。

这是在你的例子是坏消息,因为输入(以毫秒为单位的当前UTC时间)具有相对小的可能值的范围。 例如,如果攻击者知道的RNG在最近48小时内接种,可缩小种子至低于2个28个可能的值,即你只有27熵的比特。

如果在另一方面,你已经使用了默认SecureRandom()在Windows上的构造函数,它会调用本地CryptoGenRandom函数来获得一个128位的种子。 因此,通过指定自己的种子,你已经削弱了安全性。

如果你真的想覆盖默认的种子(如用于单元测试),你还应该指定的算法。 例如

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("abcdefghijklmnop".getBytes("us-ascii"));

另请参阅如何解决性能问题与Java的SecureRandom?
而这篇博客文章: http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/



Answer 2:

我认为这是最好让SecureRandom的种子本身。 这是通过调用的nextBytes它后立即创建(调用过setSeed将防止这一点)来完成。

final byte[] dummy = new byte[512];
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.nextBytes(dummy);

你想用SHA1PRNG,因为它保证了快速的非阻塞实现甚至在Linux上,其中默认是没有的。



Answer 3:

该代码是相当安全的,因为它不只是使用给种子的随机种子。

它不是比只使用更加随意。

SecureRandom randomizer = new SecureRandom();


文章来源: SecureRandom safe seed in Java