在安全的随机数生成器中使用可预测的种子¶
ID: java/predictable-seed
Kind: problem
Security severity: 9.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-335
- external/cwe/cwe-337
Query suites:
- java-code-scanning.qls
- java-security-extended.qls
- java-security-and-quality.qls
在伪随机数生成器中使用可预测的种子会导致其生成的数字可预测。
建议¶
如果伪随机数生成器的可预测性无关紧要,那么请考虑使用来自 java.util
的速度更快的 Random
类。如果伪随机数生成器必须生成完全不可预测的值,那么要么让生成器通过不指定种子来自行安全地播种,要么指定随机生成的不可预测的种子。
示例¶
这里显示的第一个示例使用常量作为种子。根据 SecureRandom
的实现,这可能导致每次执行代码时生成相同的随机数。
这里显示的第二个示例使用系统时间作为种子。根据 SecureRandom
的实现,如果攻击者知道代码运行的时间,他们可以预测生成的随机数。
这里显示的第三个示例允许随机数生成器生成自己的种子,它将以安全的方式进行。
SecureRandom prng = new SecureRandom();
int randomData = 0;
// BAD: Using a constant value as a seed for a random number generator means all numbers it generates are predictable.
prng.setSeed(12345L);
randomData = prng.next(32);
// BAD: System.currentTimeMillis() returns the system time which is predictable.
prng.setSeed(System.currentTimeMillis());
randomData = prng.next(32);
// GOOD: SecureRandom implementations seed themselves securely by default.
prng = new SecureRandom();
randomData = prng.next(32);