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