问题描述:
?? ? ? 在对安全性要求较高的环境中,使用一个能产生可预测数值的函数作为随机数据源,会产生 Insecure Randomness 错误。电脑是一种具有确定性的机器,因此不可能产生真正的随机性。伪随机数生成器 (PRNG) 近似于随机算法,始于一个能计算后续数值的种子。
? PRNG 包括两种类型:统计学的 PRNG 和密码学的 PRNG。
? 统计学的 PRNG 可提供有用的统计资料,但其输出结果很容易预测,因此数据流容易复制。若安全性取决于生成数值的不可预测性,则此类型不适用。
? 密码学的 PRNG 通过可产生较难预测的输出结果来应对这一问题。为了使加密数值更为安全,必须使攻击者根本无法、或极不可能将它与真实的随机数加以区分。
? 通常情况下,如果并未声明 PRNG 算法带有加密保护,那么它有可能就是一个统计学的 PRNG,不应在对安全性要求较高的环境中使用,其中随着它的使用可能会导致严重的漏洞(如易于猜测的密码、可预测的加密密钥、会话劫持攻击和 DNS 欺骗)。
问题代码:
Random random = new Random();
...
while (hashSet.size() < isNewProductCount) {
//随机数漏洞代码
hashSet.add(random.nextInt(newProductList.size()));
}
...
解决方案:
使用?java.security.SecureRandom 包下的安全随机数对象即可解决漏洞:
SecureRandom secureRandom = new SecureRandom();
...
while (hashSet.size() < isNewProductCount) {
hashSet.add(random.nextInt(newProductList.size()));
}
...
?