问题描述
不久前,我开发了一个用户可以购买门票的 Web 应用程序.由于我们客户的流程运作方式,您购买后实际上得到的是一个包含票号的 URL.
A while ago I worked on a web application where users could buy tickets. Due to the way our client's processes worked, what you effectively got as a result of your purchase was a URL with the ticket number in it.
这些是在中东购买房产的门票,每张门票的潜在价值约为 3,000,000 美元.显然,抛出顺序整数是个坏主意.我们使用 GUID,因为它们基本上无法猜测,但我的问题是:它们足够安全吗?
These were tickets to buy property in the Middle East, and each ticket was potentially worth around $3,000,000. Clearly dishing out sequential integers would have been a bad idea. We used GUIDs as they're basically unguessable, but my question is: are they secure enough?
据我了解,.NET 生成的 GUID 完全是伪随机的(除了一些不变的位).但是,我不知道使用什么算法来生成它们.
As I understand it, the GUIDs .NET produces are totally pseudo-random (except for a few non-varying bits). However, I don't know what algorithm is used to generate them.
MSDN 文档告诉我们 Random
快速且不安全,并且 RNGCryptoServiceProvider
既慢又安全.也就是说,可以合理地假设有人可以付出足够的努力来预测 Random
的结果,而不是 RNGCryptoServiceProvider
的结果.
The MSDN documentation tells us that Random
is fast and insecure, and RNGCryptoServiceProvider
is slow and secure. That is, it's reasonable to assume someone could put in enough effort to predict the outcome of Random
, but not of RNGCryptoServiceProvider
.
如果您看到足够长的 GUID 序列,是否可以预测未来的 GUID?如果是,你需要看多少个?
If you saw a long enough sequence of GUIDs, would it be possible to predict futures ones? If so, how many would you need to see?
[在我们的特殊情况下,稍后会进行物理安全检查 - 您必须出示您用来买票的护照 - 所以如果有人猜到了某人也不会太糟糕else 的 GUID,所以我们当时并没有出汗.使用 GUID 作为数据库键的便利性使其成为一种有用的数据类型.]
[In our particular case there were physical security checks later on - you had to present the passport you used to buy your ticket - so it wouldn't have been too bad if someone had guessed someone else's GUID, so we didn't sweat it at the time. The convenience of using the GUID as a database key made it a useful datatype to use.]
所以答案是不够".
使用以下 0xA3 的答案,以及来自 question 他链接到,以下代码将生成一个加密随机 GUID,该 GUID 对 RFC 4122 的第 4.4 节:
Using 0xA3's answer below, and following links from the question he linked to, the following code will generate a cryptographically random GUID that's valid by Section 4.4 of RFC 4122:
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 位的非常随机".数据,它们是安全不可预测的.
This produces GUIDs much more slowly than Guid.NewGuid()
, but with 122 bits of "very random" data, they are safely unpredictable.
当然,任何加密随机文本都可以作为票号,但 GUID 非常方便.:-)
Of course, any cryptographically random text would have done for a ticket number, but GUIDs are pretty handy. :-)
与其他版本 4 GUID 一样,没有绝对的唯一性保证,但几率令人印象深刻.只要您的数量少于 326,915,130,069,135,865(即 sqrt(-22^122ln(0.99))) 个 GUID 同时运行,您可以 99% 以上确定没有冲突.换句话说:如果像我一样,如果您的应用程序几乎所有内容都超过 int.MaxValue
,那么您的应用程序将到处出现溢出错误,那么您可以超过 99.99999999999999999% 确定没有冲突(即e^-(((2^31-1)^2)/(2*2^122))).这比您确信陨石不会在应用程序上线后的一秒钟内消灭地球上的大部分生命(即 每亿年一个).
As with other version 4 GUIDs there's no absolute guarantee of uniqueness, but the odds are impressive. So long as you have fewer than 326,915,130,069,135,865 (i.e. sqrt(-22^122ln(0.99))) GUIDs in play simultaneously, you can be more than 99% sure there are no collisions. Put another way: if like mine your application will have overflow errors all over the place if you have more than int.MaxValue
of pretty much anything, you can be more than 99.9999999999999999% sure of no collisions (i.e. e^-(((2^31-1)^2)/(2*2^122))). This is about a thousand times more sure than you can be that a meteorite won't wipe out most of life on Earth within one second of the application going live (i.e. one per 100 million years).
推荐答案
UUID/GUID 由 RFC4122.虽然版本 4 UUID 是从随机数创建的 Section 6 明确安全声明:
UUIDs/GUIDs are specified by RFC4122. Although Version 4 UUIDs are created from random numbers Section 6 makes an explicit statement on security:
不要假设 UUID 很难猜出;它们不应该被使用作为安全能力(仅仅拥有授权的标识符访问),例如.一个可预测的随机数源将加剧局势.
Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example. A predictable random number source will exacerbate the situation.
在这个问题中也可以找到关于 GUID 随机性的一个很好的讨论:
A good discussion of the randomness of GUIDs can also be found in this question:
System.Guid.NewGuid() 有多随机?(拍两张)
这篇关于GUID 的安全性如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!