问题描述
这段代码是否安全?
SecureRandom randomizer = new SecureRandom(String.valueOf ())。getBytes());
这是正确的实现安全随机种子的方法吗?
不,你应该避免 SecureRandom(byte [])
构造函数。
这是不可移植的,因为它在Windows上与其他操作系统的行为不同。
在大多数操作系统上,默认算法是NativePRNG,它从操作系统获取随机数据(通常/ dev / random
),忽略
在Windows上,默认算法是SHA1PRNG,它将您的种子与计数器组合,并计算结果的散列。 b
$ b
在您的示例中,这是一个坏消息,因为输入(当前UTC时间(以毫秒为单位))具有相对较小的可能值范围。例如,如果攻击者知道RNG在过去48小时内被播种,它们可以将种子缩小到小于2个可能的值,即,只有27位的熵。
另一方面,如果你在Windows上使用了默认的 SecureRandom()
构造函数, c $ c> CryptoGenRandom 函数来获取128位种子。所以通过指定你自己的种子,你已经削弱了安全性。
如果你真的想覆盖默认种子(例如单元测试),你也应该指定算法。例如
SecureRandom sr = SecureRandom.getInstance(SHA1PRNG);
sr.setSeed(abcdefghijklmnop.getBytes(us-ascii));
另请参阅
和此博客帖子:http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/
Is this piece of code safe?
SecureRandom randomizer = new SecureRandom(String.valueOf(new Date().getTime()).getBytes());
Is this the right way to instance the seed of secure random?
No, you should avoid the SecureRandom(byte[])
constructor. It is both unsafe and non-portable.
It is non-portable because it behaves differently on Windows vs. other operating systems.
On most OSes, the default algorithm is "NativePRNG", which obtains random data from the OS (usually "/dev/random"
) and ignores the seed you provide.
On Windows, the default algorithm is "SHA1PRNG", which combines your seed with a counter and computes a hash of the result.
This is bad news in your example, because the input (the current UTC time in milliseconds) has a relatively small range of possible values. For example if an attacker knows that the RNG was seeded in the last 48 hours, they can narrow the seed down to less than 2 possible values, i.e. you have only 27 bits of entropy.
If on the other hand you had used the default SecureRandom()
constructor on Windows, it would have called the native CryptoGenRandom
function to get a 128-bit seed. So by specifying your own seed you have weakened the security.
If you really want to override the default seed (e.g. for unit testing) you should also specify the algorithm. E.g.
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("abcdefghijklmnop".getBytes("us-ascii"));
See also How to solve performance problem with Java SecureRandom?
and this blog post: http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/
这篇关于SecureRandom Java中的安全种子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!