我们观察到,近200,000个UUID已经重播了两个月,我想知道是否有人见过类似的东西。
使用UUID.randomUUID()生成UUID。在深入研究这个问题(查看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实例上。这是过去曾见过/经历过的事吗?似乎应该“永远不会发生的事情”......
答案 0 :(得分:15)
从JDK 1.6源代码来看,UUID.randomUUID()
实例上的java.util.SecureRandom
源代码确实存在。如果你有一个重复的UUID序列,那么要么你非常幸运(或者非常不幸,取决于观点),或者有人使用VM快照,或者你的Java配置中有些可疑。
在拍摄VM快照时,您会记录机器的完整实时状态,包括的进程和RAM。如果存在具有已实例化的SecureRandom
实例的实时进程,则还原快照将恢复该状态,因此每次还原时SecureRandom
输出的随机值序列将相同,直到SecureRandom
从/dev/urandom
(/dev/urandom
不断收集&#34;随机&#34;物理事件中重新种植,直到SecureRandom
状态不会影响SecureRandom
状态。下一次重播。)
Java配置可能会影响SecureRandom
,因为SecureRandomSpi
不是PRNG,而是由正式注册的加密提供程序提供的/dev/urandom
实例周围的shell。 Sun的JDK附带了一个默认实现,通常以系统的资源(Linux上的java.security.egd
)为基础。但是,这可以配置;查找securerandom.source
系统属性,以及java.security
文件中的/dev/random
属性。默认提供程序也可以与替代实现一起替换,该替换实现以不同方式执行(并且可能非常差)。有关详细信息,请参阅this answer。验证确实使用了哪些随机源可能有点复杂,但您可以尝试使用strace启动您的流程,该{{3}}会显示系统调用,因此会在某些位置打开/dev/urandom
或{{1}}点。
如果您的Java配置正常,和没有带有VM快照的游戏,和您确定您确实获得了与之前相同的UUID序列,那么你真的真的应该购买一张强力球票(但我真的不相信这种情况)。