【发布时间】:2016-01-27 15:29:43
【问题描述】:
我们观察到,近 200,000 个 UUID 的集合相隔两个月重播,我想知道是否有人见过类似的情况。
UUID 是使用 UUID.randomUUID() 生成的。在深入研究这个(查看 java 源代码)时,randomUUID() 在后台使用 SecureRandom(),而后者又使用 NativePRNG。据我了解,NativePRNG 使用 /dev/urandom 来获取它的种子。这当然令人费解——不知何故 /dev/urandom 相隔两个月将相同的种子返回给 NativePRNG。据我所知,一旦实例化 PRNG 就不会重新播种。这是一个长时间运行的作业,它监听消息并使用 UUID 作为它的 ID。伪代码很简单:
< receive message>
String uuid = UUID.randomUUID().toString();
String fname = h.composeArtifact(uuid);
操作系统是 Centos 6,在运行 JDK1.6 的 AWS EC2 实例上。这是任何人过去见过/经历过的事情吗?似乎是那种“永远不会发生”的事情......
【问题讨论】:
-
我不确定这是一个安全问题,而是一个 java 内部问题。
-
在这两种情况下它们都是从新创建的实例生成的吗?
-
如果用于保存
UUID seed的任何内部存储是通过 Chef / Puppet / VM 快照的一部分管理的文件怎么办?我认为询问这个据称独特的种子是如何存储和操纵的,以及操作系统是否有机会将其重置为过去的值是合理的。同样有趣的是,Java 中使用的 PRNG 是否可能会遍历一小部分值,攻击者检测到的频率和方式。 -
您说“一组 200k UUID”——其中有多少?
-
我看到的完全一样。我只是使用
testng运行测试@Test(threadPoolSize = 50, invocationCount = 2)。当我设置invocationCount = 1时,我的测试运行良好。但是当我将它设置为 2 或更多同时并行线程时,测试失败了。我一直在挖掘并意识到我使用UUID.randomUUID()为我的测试对象生成的 id 在所有线程中都是完全相同的。我能够通过为每个线程添加随机延迟来规避这个问题。换句话说:如果线程完全在同一时间运行,则生成的 UUID 在所有线程中都是相同的。