概述
如何在Flash和/或JavaScript客户端生成真正的全局唯一标识符?我是否可以使用当前浏览器/Flash中可用的随机数生成器(RNG)来实现,还是必须使用服务器端随机性构建组合ID?
详情
我需要为对象生成全局唯一标识符。 我有多个使用Java编写的服务器端“系统”,它们需要能够交换 ID;每个系统还具有一组Flex / JavaScript客户端,这些客户端实际上为新对象生成ID。 我需要确保在一组不相关的系统中具有全局唯一性;例如,我需要能够合并/同步两个独立系统的数据库。 我必须保证这些ID之间永远不会发生冲突,并且我永远不需要更改创建后的对象的ID。 我需要能够在Flash和JavaScript客户端中生成ID,而无需针对每个ID联系服务器。 只要不经常与服务器联系,就可以依赖某些由服务器提供的种子或系统ID的解决方案。 完全断开连接的解决方案更可取。 同样,不需要事先注册系统的解决方案比依赖中央管理机构(例如MAC地址中的OUI)的解决方案更可取。
我知道显而易见的解决方案是“使用UUID生成器”,例如Flash中的UIDUtil。 但是,该函数明确声明不具备全局唯一性。 总的来说,我担心依赖PRNG保证全局唯一性。
建议的解决方案
完全依靠客户端中的安全随机数生成器。
Flash 11+具有flash.crypto.generateRandomBytes; JavaScript具有window.crypto,但它相当新,并且在IE中不受支持。 还有像sjcl这样的解决方案,它使用鼠标添加熵。
我知道如果有一个完美的随机数生成器,2122的随机UID碰撞的可能性非常小,但我担心在javascript或flash客户端中实际上无法获得这种程度的随机性。我进一步担心即使是加密随机数生成器的典型用例也与我的不同:对于会话密钥等,只要攻击者无法预测,碰撞就是可以接受的。在我的情况下,碰撞是完全不可接受的。我真的应该依靠安全随机数生成器的原始输出来生成唯一ID吗?
生成一个包含系统、会话和对象ID的复合ID。
一个明显的实现方法是在服务器安装时创建系统UUID,在每个客户端登录时保留一个会话ID(例如在数据库中),然后将系统和会话ID发送到客户端,客户端将保留一个每个会话的计数器。UID将是三元组:系统ID、会话ID、客户端计数器。
我可以想象直接串联它们或使用加密哈希函数对它们进行哈希。我担心哈希本身可能会引入碰撞,特别是如果哈希的输入与输出大小相近。但哈希将掩盖系统ID和计数器,这可能会泄露信息。
另一种解决方案是在安装时生成系统ID,或者使用类似DOI的中央注册表来分配唯一的系统ID。然而,这需要更多的协调,但我想这是真正保证全球唯一性的唯一方式。
关键问题
- 基于随机还是复合?
- 是否包含系统ID?
- 如果包含系统ID:生成一个随机的系统ID还是使用中央注册表?
- 包含时间戳或其他nonce吗?
- 要哈希还是不要哈希?