Random函数的安全性问题与SecureRandom

电脑是一种具有确定性的机器, 因此不可能产生真正的随机性。 伪随机数生成器 (PRNG) 近似于随机算法, 始于一个能计算后续数值的种子。
PRNG 包括两种类型: 统计学的 PRNG 和密码学的 PRNG。 统计学的 PRNG 提供很多有用的统计属性, 但其输出结果很容易预测, 因此容易复制数值流。 在安全性所依
赖的生成值不可预测的情况下, 这种类型并不适用。 密码学的 PRNG 生成的输出结果较难预测, 可解决这一问题。 为保证值的加密安全性, 必须使攻击者根本无法、 或几
乎不可能鉴别生成的随机值和真正的随机值。 通常情况下, 如果并未声明 PRNG 算法带有加密保护, 那么它很可能就是统计学的 PRNG, 因此不应在对安全性要求较高的
环境中使用, 否则会导致严重的漏洞(如易于猜测的密码、 可预测的加密密钥、 Session Hijacking 和 DNS Spoofing) 。
示例: 下面的代码可利用统计学的 PRNG 为购买产品后仍在有效期内的收据创建一个 URL。

String GenerateReceiptURL(String baseUrl) {
Random ranGen = new Random();
ranGen.setSeed((new Date()).getTime());
return (baseUrl + ranGen.nextInt(400000000) + ".html");
}
这段代码使用 Random.nextInt() 函数为它生成的收据页面生成“唯一”的标识符。 由于 Random.nextInt() 是统计学的 PRNG, 攻击者很容易猜到其生成的字符
串。 尽管收据系统的底层设计并不完善, 但若使用不会生成可预测收据标识符的随机数生成器(如密码学的 PRNG) , 就会更安全些

解决方案
当不可预测性至关重要时, 如大多数对安全性要求较高的环境都采用随机性, 这时可以使用密码学的 PRNG。 不管选择了哪一种 PRNG, 都要始终使用带有充足熵的数值
作为该算法的种子。 (诸如当前时间之类的数值只提供很小的熵, 因此不应该使用。 )
Java 语言在 java.security.SecureRandom 中提供了一个加密 PRNG。 就像 java.security 中其他以算法为基础的类那样, SecureRandom 提供了与某
个特定算法集合相关的包, 该包可以独立实现。 当使用 SecureRandom.getInstance() 请求一个 SecureRandom 实例时, 您可以申请实现某个特定的算法。 如
果算法可行, 那么您可以将它作为 SecureRandom 的对象使用。 如果算法不可行, 或者您没有为算法明确特定的实现方法, 那么会由系统为您选择 SecureRandom果算法可行, 那么您可以将它作为 SecureRandom 的对象使用。 如果算法不可行, 或者您没有为算法明确特定的实现方法, 那么会由系统为您选择 SecureRandom
的实现方法。
Sun 在名为 SHA1PRNG 的 Java 版本中提供了一种单独实现 SecureRandom 的方式, Sun 将其描述为计算:
“SHA-1 可以计算一个真实的随机种子参数的散列值, 同时, 该种子参数带有一个 64 比特的计算器, 会在每一次操作后加 1。 在 160 比特的 SHA-1 输出中, 只能使用64 比特的输出 1。 ”
然而, 文档中有关 Sun 的 SHA1PRNG 算法实现细节的相关记录很少, 人们无法了解算法实现中使用的熵的来源, 因此也并不清楚输出中到底存在多少真实的随机数值。
尽管有关 Sun 的实现方法网络上有各种各样的猜测, 但是有一点无庸置疑, 即算法具有很强的加密性, 可以在对安全性极为敏感的各种内容中安全地使用。

使用
SecureRandom random1 = SecureRandom.getInstance("SHA1PRNG");
SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");
for (int i = 0; i < 5; i++) {
    System.out.println(random1.nextInt() + " != " + random2.nextInt());
}
结果
704046703 != 2117229935
60819811 != 107252259
425075610 != -295395347
682299589 != -1637998900
-1147654329 != 1418666937

---------------------
版权声明:本文为CSDN博主「master_bro」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_31391283/article/details/80112298

原文地址:https://www.cnblogs.com/sea520/p/11338874.html