昨天我问Are GUIDs generated on Windows 2003 safe to use as session IDs?,结合本文GUIDs are globally unique, but substrings of GUIDs aren't的答案促使我考虑将当前使用GUID的机制替换为Cookie中的会话ID。
因为进行这项改变需要做一些工作,所以我决定在我的Vista PC上运行一个快速GUID测试,看看一系列GUID是否显然是确定性的(我担心的是攻击者是否能够获得我的服务器生成的一系列GUID,他们可以生成新的匹配的。)
在Raymond Chen的文章(从1998年引用这个非常古老的规范UUIDs and GUIDs )中,GUID由以下内容组成:
如果我生成10个GUID,前15个ASCII字符(不包括' - ')是时间戳,接下来的12个ASCII字符是计算机标识符,接下来的3.5个ASCII字符是随机的,最后1.5个字符是固定的
使用.Net System.Guid.NewGuid()在我的Vista PC上获取10个GUID:
b4e95ead-3619-4dc2-9102-cf7ab0efd927
a45ee719-decd-46b2-8355-7becbe406f74
9af68d75-35a0-4907-b6ab-f15e33acfe96
bed88fa3-3209-4a19-97dd-85d5428ea5f4
123cb39b-8d81-41c6-8894-f1257a8f7606
e2b1f6b1-5791-4a18-80a9-5dc668574ecb
c52aa660-2629-4659-bb83-5583081e5a1c
76eda32d-ceda-412e-8ade-30c47416e954
cbc4d45e-7281-40d2-9f90-00539b04fe98
be36524c-267c-4791-bc9e-3c20b29d7615
快速直观检查中唯一可识别的模式是第13个ASCII字符始终为4。
我再次想知道,依靠System.Guid生成伪随机会话ID是否足以保护一个Web应用程序,其中破解会话ID的价值最多可达数千美元?
更新:我现在计划使用以下方法生成会话ID,而不是使用GUID。我正在将384位随机数转换为0x00字节字符串,以便它适合在HTTP cookie中使用。
RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider();
byte[] myKey = new byte[48];
rngProvider.GetBytes(myKey);
string sessionID = null;
myKey.ToList().ForEach(b => sessionID += b.ToString("x2"));
Console.WriteLine(sessionID);
答案 0 :(得分:10)
这不是一个完整的答案,但我可以告诉你,第13个十六进制数字总是4,因为它表示用于生成GUID的算法的版本(id est,v4);另外,我引用维基百科:
WinAPI GUID的密码分析 发电机显示,自从 V4 GUID序列是伪随机的, 鉴于初始状态可以 预测接下来的250 000个GUID 由函数UuidCreate返回。 这就是为什么不应该使用GUID的原因 在密码学中,例如,作为随机密钥。
本文的其余部分及其参考文献:http://en.wikipedia.org/wiki/Guid
- 编辑 -
从安全角度来看,我建议你生成你想要的会话ID,然后加密签名;这样你可以打包你想要的任何信息,然后在最后打一个签名 - 可能的问题是你的密钥的大小/强度和cookie的最终大小之间的权衡。 GUID作为ID很有用,但我只依靠专用的加密技术来保证安全。
答案 1 :(得分:7)
我建议您使用System.Security.Cryptography.RandomNumberGenerator。这旨在产生无法逆向工程的数字。 Guid的动机是独特的。您可以将GUID和安全随机数组合在一起,但128位安全随机数在练习时永远不会发生冲突。
答案 2 :(得分:1)
一些注意事项:
如果您真的担心拥有强大的会话ID,那么可能无法从机外确定的加密安全哈希值是您最好的方法。也许从某些内部文档或数据源生成one-time pad甚至可以工作。
答案 3 :(得分:0)
你想做什么?你想要一个随机数的来源吗?
结帐random.org和hotbits。许多年前,我有一个Java库,可以从这些来源收集数字,并将它们连接在一起,以获得一个非常漂亮的随机系列(虽然它假设这两个网站不在cahootz中)。
答案 4 :(得分:-1)
简短的回答是,如果你想阻止会话ID猜测和破解,没有guid的强度不足以产生会话ID。
出于同样的原因,您不希望将GUID用作AES密钥,您不希望将它们用于任何类型的敏感标识。
GUID非常适用于它们的设计目标:数学保护的唯一ID,永不重复。
即使破解一个会话ID只值1000美元,想象一下如果这样做了100次。现在,你正在谈论严肃的金光闪闪。
我知道这是一个简单的方法来使用GUID但抗拒,并通过采取适当的预防措施来充分保护您的应用程序来应对痛苦。您的用户会感谢您。
答案 5 :(得分:-1)
考虑到获得一个guid的可能性,几乎不可能获得重复的guid。这是一些快速的数学事实
世界上的沙粒75,000,000,000,000,000,000
GUID数量340,282,366,920,938,463,463,374,607,431,770,000,000