我知道这听起来像是一个毫无意义的问题,但请听我说...
我基本上想知道我是否可以信任 GUID 生成一个 100% 的时间唯一且无法预测的值。
我基本上是在为一个网站滚动我的登录系统,并想知道 GUID 对于会话 cookie 是否足够安全。
在评估答案时,将非常感谢任何有关如何生成 GUID 的背景。
感谢您提供重复问题的链接,但是,我的问题特定于 .Net 框架。
没有固定长度的值可以保证 100% 唯一(只要调用它足够多次,给予或接受宇宙结局;-p) - 但它可能非常、非常、非常不可能复制。
我不能说序列号的可预测性,但它会是独一无二的。不过,我认为您最好使用 System.Security.Cryptography 中的随机数生成器。将随机数与单调递增的值(时间)联系起来以生成您的唯一密钥,您可以确定它是唯一的且不可预测的。
System.Guid.NewGuid() 的文档不保证随机性,因此虽然当前的实现基于随机数生成器(它是算法的第 4 版,它是在使用 MAC 的第 1 版出现隐私问题后设计的地址;其他系统(例如 Apple 的 OS X)仍使用该算法的版本 1)。
因此,虽然 System.Guid.NewGuid() 生成唯一值的概率非常高,但您不能对其可预测性做出任何假设,因为文档中没有指定。
我不知道 .NET,但UUID 算法的定义相当精确。
编辑:如果您查看适当的位(请参阅维基百科条目),那应该解释正在使用哪个版本的 UUID。
编辑2:您使用“安全”一词的危险信号,它告诉我您最好使用定义明确的加密方法。例如,当在服务器上生成会话 ID 时,为什么不做一些简单的事情,比如将 MD5 哈希应用于以下适当子集的连接:{客户端计算机 IP 地址、顺序递增的计数器、您选择的固定秘密常量、您选择的随机数生成器的输出等} ?
假设 System.Guid.NewGuid 使用 CoCreateGuid,它根本不是随机的。从历史上看,用于创建 guid 的算法是结合来自网络适配器的 MAC 地址,以及时间等其他一些内容。我不确定算法是否已经改变。虽然它肯定不是随机的,但它保证是唯一的。
我基本上想知道我是否可以信任 GUID 生成一个100% 的时间唯一且无法预测的值。
我基本上是在为一个网站滚动我的登录系统,并想知道GUID 对于会话 cookie 是否足够安全。
简短的回答:根本没有。需要注意的是,唯一性和随机性是完全不同的。如果你有一个通用计数器(比如在熟食店取一个数字),这些数字是独一无二的,但完全可以预测。
正如 Bochu 上面所说,Raymond 的帖子在这里谈到了它: https ://blogs.msdn.microsoft.com/oldnewthing/20120523-00/?p=7553/
GUID 生成算法是为唯一性而设计的。它不是为随机性或不可预测性而设计的。确实,如果您查看之前的讨论,您会发现所谓的算法 1 是非随机的且完全可预测的。...即使是第 4 版 GUID 算法(基本上说“将版本设置为 4 并用随机或伪随机数填充其他所有内容”)也不能保证是不可预测的,因为该算法没有指定随机数的质量数发生器。
对于安全随机数,您需要一个加密安全的随机数生成器。
顺便说一句,“滚动我自己的登录系统”是一个安全危险信号——如果我没有指出这一点,我就会失职。
根据定义,GUID 在所有方面都是唯一的。曾几何时,有一些生成顺序 GUID 的 GUID0 生成例程,但这些都是...... Win98 中的问题,我认为,并且由 Microsoft 修复。
您应该能够相信生成的 GUID 是唯一的,并且永远不会重复或重新生成。
(编辑:话虽如此,我们都知道,如果字符串长度固定,则字母数字字符串具有固定数量的排列。但在 GUID 的情况下,排列的数量是经济的*。)
(*该死,XKCD 的提议“天文”数字在哪里还不够大?)