System.Guid.NewGuid() 有多隨機?(拿兩個)
在開始將其標記為重複之前,請閱讀我的內容。另一個問題有一個(很可能)不正確的接受答案。
我不知道 .NET 如何生成它的 GUID,可能只有 Microsoft 會這樣做,但它很可能只是呼叫CoCreateGuid()。然而,該函式被記錄為呼叫UuidCreate()。並且用於創建 UUID 的算法有很好的文件記錄。
長話短說,儘管如此,它似乎
System.Guid.NewGuid()確實使用了版本 4 UUID 生成算法,因為它生成的所有 GUID 都符合條件(自己看看,我嘗試了幾百萬個 GUID,它們都匹配)。換句話說,這些 GUID幾乎是隨機的,除了一些已知位。
這又提出了一個問題——這種隨機性有多隨機?每個優秀的小程序員都知道,偽隨機數算法的隨機性與其種子(又稱熵)一樣隨機。那麼種子有什麼用
UuidCreate()呢?PRNG 多久重新播種一次?它是否具有強大的加密功能,或者如果兩台電腦意外同時呼叫,我是否可以期望相同的 GUID 開始傾瀉而出System.Guid.NewGuid()?如果收集到足夠多的順序生成的 GUID,是否可以猜測 PRNG 的狀態?**補充:**為了澄清,我想知道我可以相信它有多隨機,因此 - 我可以在哪裡使用它。所以,讓我們在這裡建立一個粗略的“隨機性”尺度:
- 基本隨機性,以目前時間為種子。可用於在紙牌中洗牌,但幾乎沒有其他用途,因為即使不嘗試也很容易發生碰撞。
- 更高級的隨機性,不僅使用時間,還使用其他機器特定的種子因素。也許在系統啟動時也只播種一次。這可用於在數據庫中生成 ID,因為不太可能出現重複。儘管如此,這對安全性不利,因為可以通過足夠的努力來預測結果。
- 加密隨機,使用設備雜訊或其他高級隨機源作為種子。每次呼叫或至少經常重新播種。可用於會話 ID、分發給不受信任的各方等。
我在考慮是否可以將它們用作 DB ID 時想到了這個問題,以及Guid.comb算法的實現
System.Guid.NewGuid()(如 NHibernate 那樣)是否存在缺陷。
答案是:你不需要知道這一點。如相關問題的已接受答案所述:
GUID 不保證隨機性,它保證唯一性。
**RFC4122**中對安全性和隨機性做出了更強有力的聲明,它指定了 UUID 格式:
不要假設 UUID 很難猜;例如,它們不應該用作安全功能(僅擁有授予訪問權限的標識符)。一個可預測的隨機數源會加劇這種情況。
其他任何東西都是實現細節(並且可能是主題更改)。
Windows 細節
通常,人們聲稱 Windows 上的行為已記錄在案,因此可以保證 GUID 是加密安全的。
現在存檔的[MS-SECO] Windows 安全概述文件在附錄 A 中提到:
儘管只有一小部分版本 4 GUID 需要加密隨機性,但 Windows 中建構的所有版本 4 GUID 的隨機位都是通過 Windows CryptGenRandom 加密 API 或等效的(用於生成加密密鑰的相同來源)獲得的。
此外,同一文件的第 2.5.5 節明確提到使用“秘密 GUID”值作為隨機數或身份驗證器。
但是:這段產品行為文件不是您通常可以基於產品安全性的規範(特別是在 .NET 的上下文中)。
實際上,上面的文件描述了特定產品的**實現細節。即使目前的 Windows 和 .NET Framework 4.x 實現在 Windows 上產生真正隨機的版本 4 UUID 值,也不能保證將來或在其他 .NET 平台(例如 Mono、Silverlight、CF、.NET核心等)。
System.Guid.NewGuid舉個例子,.NET Core 早期版本中使用的 UUID 算法取決於平台,您可能會獲得版本 1 UUID(在 BSD 上)。