这将是Kai Michaelis,JörgSchwenk和我撰写的论文的总结,该论文在RSA Conference 2013的密码学家会议上发表 。 你可以得到我的演讲的幻灯片在这里和我们的全文在这里 。 我们对PRNG(主要是SecureRandom)附带的常见Java库生成的随机序列进行了分析,发现在特殊条件下存在明显的弱点。 为了使文章尽可能简短,PRNG使用的算法的描述,详细的错误描述和统计测试的结果均被省略,但可在本文中找到。 我们的研究涵盖PRNG本身以及用于播种的熵收集器(例如,如果没有实数生成器可用)。
底线:当需要良好的随机性时不要使用PRNG!
质量通过多种方式分级。 首先,我们进行了代码分析,并(成功地)尝试查找和识别导致严重缺陷的编码错误。 其次,我们对生成的随机序列进行了统计检验。 最后,我们强调了在特殊条件下(高系统负载,某些组件不可用等)的算法。
第一个库:
尽管经过重试,但Apache Harmony仍可作为Android源代码的一部分(请参见此处 )保留下来,因此是数百万种设备的一部分。
弱点
发现的错误之一直接影响Android平台。 其他错误仅存在于Apache Harmony中,而不存在于Android源代码中。
FIRST –创建自种子的SecureRandom实例时(通过调用不带参数的构造函数并随后进行setSeed()调用),代码在插入起始值后无法调整字节偏移(状态缓冲区中的指针)。 这将导致计数器和填充的开头(32位字)覆盖部分种子而不是附加种子。 第二 –在类似Unix的操作系统下运行时,新的SecureRandom实例从urandom或随机设备中植入了20个字节的种子。 如果两者均不可访问,则该实现将提供备用种子设施。 一旦播种工具收集了请求的字节数,出于未知原因,最高有效位将设置为零。 结果,对于每个请求的字节,SecureRandom实例的有效种子仅为7/8,从而将安全性(由于第一个错误,仅64位)降低了8位至56位。 更糟糕的是,由于另一个无效的模减少,单个调用播种功能的熵被限制为仅31位。 当查看生成的字节时,熵收集器的问题显而易见。 下图描述了单个点的两个连续字节。
每个方向上都完全缺少127以上的值。
第二个库:
GNU Classpath部分由著名的IcedTea项目使用,因此最著名的是Linux系统上的64位Java Browser-plugin。
弱点
该库在内部状态方面存在重大缺陷。 该错误与用于哈希函数的相同的初始化向量(IV)有关。 这将内部状态的未知字节数从32个减少到只有20个。EntropyCollector算法很难预测,这很好,但是它依赖于争夺CPU时间的线程,这很容易受到影响(通过将系统置于高负载)。 线程运行时检查不够严格,无法确保良好的随机性。 下图显示了有关平均分配输出的困难,留下了较大的色块。 该图显示了熵收集器在高系统负载下的性能。
相比之下,熵收集器在正常情况下的表现与预期相同:
第三图书馆:
Java SE的官方免费开源实现在很大程度上与Oracle提供的版本相同。 大多数Java用户很可能依赖此代码。
弱点
代码审查没有明显的弱点。 Entropy Collector依赖于线程递增计数器,但是与GNU Classpath相反,它对运行时的要求最低。 结果图填充得非常平衡。
第四图书馆:
该库与其他库有所不同,因为它只是用于各种密码算法的非常全面的库。 它附带多种替换品 BouncyCastle的熵收集器可以在两种操作模式下运行,即快速模式和慢速模式,其中不同数量的字节用于随机输出。
弱点
与OpenJDK案例一样,Bouncy Castle的SecureRandom替代品(DigestRandomGenerator)没有发现明显的错误。 相反,已知VMPCRandomGenerator容易受到攻击。 两种模式下的熵收集器都可以非常平衡地填充图形。
摘要
非常有趣的是受检查的实现的有限且不可配置的内部状态大小。 几乎所有实现都依赖SHA-1作为哈希(压缩)功能。 因此,它们对于大于160bit的密钥生成似乎没有用。 只有Apache Harmony依赖于512位的内部状态,但是会遭受编码错误。 该博客文章省略了许多详细信息和统计信息,以便仅对库进行快速而肮脏的审查-如果您对更多详细信息和进一步的结果感兴趣,欢迎您阅读全文。
参考:来自Java安全和相关主题博客的JCG合作伙伴 Christopher Meyer的Java伪随机数生成器(PRNG)中的弱点 。
翻译自: https://www.javacodegeeks.com/2013/03/weaknesses-in-java-pseudo-random-number-generators-prngs.html