不久之前,我在一个用户可以购买门票的网络应用程序上工作.由于我们客户的流程的运作方式,您购买后实际获得的是一个带有票号的URL.
这些是在中东购买房产的门票,每张门票的价值可能在300万美元左右.显然抛出顺序整数本来是个坏主意.我们使用GUID,因为它们基本上是不可知的,但我的问题是:它们足够安全吗?
据我所知,GUIDs .NET产生的是完全伪随机的(除了一些非变量位).但是,我不知道使用什么算法来生成它们.
MSDN文档告诉我们Random快速且不安全,并且RNGCryptoServiceProvider速度慢且安全.也就是说,假设有人可以投入足够的努力来预测结果Random,但不是RNGCryptoServiceProvider.
如果您看到足够长的GUID序列,是否可以预测期货?如果是这样,你需要看多少?
[在我们的特殊情况下,之后会进行身体安全检查 - 您必须出示用于购买机票的护照 - 所以如果有人猜到别人的GUID 就不会太糟糕,所以我们没有出汗当时.使用GUID作为数据库密钥的便利性使其成为一种有用的数据类型.]
编辑:
所以答案是"不够".
使用下面的0xA3的答案,并跟随他链接的问题的链接,以下代码将生成一个加密随机GUID,该GUID由RFC 4122的第4.4节有效:
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);
}
Run Code Online (Sandbox Code Playgroud)
这比GUID产生的速度慢得多 …
在您开始将其标记为重复之前,请将我读出来.另一个问题是(很可能)不正确的接受答案.
我不知道.NET如何生成其GUID,可能只有微软这样做,但它很有可能只是调用CoCreateGuid().但是,该函数被记录为调用UuidCreate().并且用于创建UUID的算法已被很好地记录.
长话短说,尽管如此,似乎System.Guid.NewGuid()确实使用了版本4 UUID生成算法,因为它生成的所有GUID都符合标准(参见自己,我尝试了几百万个GUID,它们都匹配).
换句话说,除了一些已知位之外,这些GUID 几乎是随机的.
这再次提出了一个问题 - 随机是如何随机的?正如每个优秀的小程序员都知道的那样,伪随机数算法只与其种子(即熵)一样随机.那么种子是UuidCreate()什么?PRNG如何重新播种?它是加密强大的,或者如果两台计算机同时意外呼叫System.Guid.NewGuid(),我可以期望相同的GUID开始倾泻吗?如果收集到足够多的顺序生成的GUID,是否可以猜测PRNG的状态?
补充:为了澄清,我想知道我可以信任的随机性因此 - 我在哪里可以使用它.那么,让我们在这里建立一个粗略的"随机性"量表:
我在想到是否可以将它们用作数据库ID时,以及Guid.comb算法的实现System.Guid.NewGuid()(如NHibernate的实现方式)是否有缺陷,我就来到了这个问题.
我想对数据库中的敏感数据使用加密安全主键 - 这是无法猜测/可预测的,并且它不能由数据库生成(我需要在持久化对象之前使用密钥).
我知道Java使用带有加密安全随机数生成器的类型4 UUID,但是我知道UUID并不是完全随机的,所以我的问题是假设无法从一组现有的uuid中预测uuids是多么安全?
如何在SQL Server中生成GUID?
我明白我应该使用newid(),但函数使用的算法是什么?它是时间/日期的哈希吗?
我已经向客户发送了10000封邮件,每封邮件都有格式链接
http://example.com/LogIn?key={guid}
Run Code Online (Sandbox Code Playgroud)
不幸的是,guid我发送的是随机guid(生成的测试数据Guid.NewGuid()),所以客户都收到了无效链接......
基于我从网络服务器收到的404s,我发了一些guid.我已经读过Windows中的guid生成器很弱,所以你可以预测你已经拥有的下一个guid.有谁知道怎么样?如果我能做到这一点,我可以使我发出的指令有效,这样链接就可以了.
基于这个问题,我想知道是否使用GUID生成一个随机的字符串和数字有任何缺陷吗?
因此,例如,如果我想要一个随机字符串和32个或更少字符的数字,我可以使用以下C#代码:
string s = Guid.NewGuid().ToString().Replace("-", "");
Run Code Online (Sandbox Code Playgroud)
如果长度需要小于32,我将截断字符串,如果需要更长,我会将多个GUID一起添加.
这种方法有哪些缺陷?
在我写完之后,我意识到一个缺陷就是它只会有字母a到f所以我会修改这个问题:
这是一个真正随机的6个字符和10个数字的序列吗?