不久前,我开发了一个 Web 应用程序,用户可以在其中购买门票。由于我们客户流程的运作方式,您购买后实际上得到的是一个包含票号的 URL。

这些是在中东购买房产的门票,每张门票的潜在值(value)约为 3,000,000 美元。显然,抛出连续整数是一个坏主意。我们使用 GUID 是因为它们基本上是不可猜测的,但我的问题是:它们是否足够安全?

据我了解,.NET 生成的 GUID 完全是伪随机的(除了一些不变的位)。但是,我不知道使用什么算法来生成它们。

MSDN 文档告诉我们 Random 速度快且不安全,而 RNGCryptoServiceProvider 速度慢且安全。也就是说,可以合理地假设有人可以付出足够的努力来预测 Random 的结果,而不是 RNGCryptoServiceProvider 的结果。

如果您看到足够长的 GUID 序列,是否有可能预测 future 的 GUID?如果是这样,你需要看多少?

[在我们的特殊情况下,后来进行了物理安全检查 - 你必须出示你用来买票的护照 - 所以如果有人猜到了别人的 GUID 也不会太糟糕,所以我们没有出汗当时。使用 GUID 作为数据库键的便利使其成为一种有用的数据类型。]

编辑:

所以答案是“不够”。

使用下面的 0xA3 的答案,以及他链接到的 0x2518122133341142 的链接,以下代码将生成一个密码随机 GUID,该 GUID 对 question 有效:

static Guid MakeCryptoGuid()
{
    // Get 16 cryptographically random bytes
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] data = new byte[16];
    rng.GetBytes(data);

    // Mark it as a version 4 GUID
    data[7] = (byte)((data[7] | (byte)0x40) & (byte)0x4f);
    data[8] = (byte)((data[8] | (byte)0x80) & (byte)0xbf);

    return new Guid(data);
}

这比 Guid.NewGuid() 产生的 GUID 慢得多,但由于 122 位“非常随机”的数据,它们是安全的不可预测的。

当然,任何加密随机文本都可以用于票号,但 GUID 非常方便。 :-)

与其他版本 4 GUID 一样,没有绝对的唯一性保证,但几率令人印象深刻。只要同时运行的 GUID 少于 326,915,130,069,135,865(即 Section 4.4 of RFC 4122),就可以 99% 以上确定没有冲突。换句话说:如果像我的一样,如果你的应用程序有超过 int.MaxValue 的几乎任何东西,你的应用程序就会到处都有溢出错误,你可以超过 99.9999999999999999% 确定没有冲突(即 0x2518124213341111)。这比陨石不会在应用程序上线的一秒内消灭地球上大部分生命(即 sqrt(-2*2^122*ln(0.99)) )的可能性要高出一千倍。

最佳答案

UUID/GUID 由 RFC4122 指定。尽管第 4 版 UUID 是从随机数创建的,但 Section 6 对安全性做出了明确声明:



在这个问题中也可以找到关于 GUID 随机性的很好的讨论:

关于.net - GUID 的安全性如何?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3652944/

10-17 02:13