.Net GUID 的確定性如何?
昨天我問Windows 2003 上生成的 GUID 是否可以安全地用作會話 ID?並且與本文結合的答案GUID 是全域唯一的,但 GUID 的子字元串不會提示我考慮替換我目前在 cookie 中使用 GUID 作為會話 ID 的機制。
因為做這個改變需要做一些工作,所以我決定在我的 Vista PC 上執行一個快速的 GUID 測試,看看一系列 GUID 是否明顯是確定性的(我擔心的是攻擊者是否能夠獲得一系列我的伺服器生成的 GUID,它們將能夠生成新的匹配的 GUID)。
在 Raymond Chen 的文章(引用了 1998 年的這個非常古老的規範UUID 和 GUID)中,GUID 由以下部分組成:
- 60位時間戳,
- 48位電腦標識符,
- 14位唯一性,和
- 六位是固定的
如果我生成 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 是否足夠強大以保護破解會話 ID 最多價值數千美元的 Web 應用程序?
更新:我現在計劃使用以下方法生成會話 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);
這不是一個完整的答案,但我可以告訴您,第 13 個十六進制數字始終為 4,因為它表示用於生成 GUID 的算法版本(id est,v4);另外,我引用維基百科:
WinAPI GUID 生成器的密碼分析表明,由於 V4 GUID 的序列是偽隨機的,給定初始狀態,可以預測函式 UuidCreate 返回的下一個 250 000 個 GUID。這就是為什麼不應在密碼學中使用 GUID,例如,作為隨機密鑰。
文章的其餘部分及其參考:http ://en.wikipedia.org/wiki/Guid
- 編輯 -
從安全的角度來看,我建議您根據自己的喜好生成會話 ID,然後對其進行加密簽名;這樣你就可以打包你想要的任何資訊,然後在最後打一個簽名——可能的問題是你的密鑰的大小/強度和 cookie 的最終大小之間的權衡。GUID 作為 ID 很有用,但我只依靠專用的加密技術來保證安全。