SecureRandom安全的Java种子

Jor*_*.S. 10 java security random encryption cryptography

这段代码安全吗?

 SecureRandom randomizer = new SecureRandom(String.valueOf(new Date().getTime()).getBytes());
Run Code Online (Sandbox Code Playgroud)

这是实例安全随机种子的正确方法吗?

fin*_*nnw 26

不,你应该避免使用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"));
Run Code Online (Sandbox Code Playgroud)

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