開發者工具 · UUID 產生器
Math.random 與 crypto.getRandomValues:每個產生器的工作原理
· 工作原理
uuid 密碼學 瀏覽器 API
兩者都傳回看起來隨機的數字,但一個是小型確定性狀態機,另一個由作業系統提供。以下是兩者的幕後作用以及為什麼 UUID 必須使用第二個。
從 Math.random 建立 UUID 的論壇片段 - 為什麼它看起來不錯並通過了每個臨時測試
論壇答案提供了一個八行的快速 UUID 工廠:從 Math.random 滾動值並將它們格式化為 8-4-4-4-12 佈局。程式碼看起來不錯並通過了每一個臨時測試。每個標識符看起來都不同,簡短的範例沒有顯示明顯的視覺模式。這不是安全敏感標識符所需的屬性。 JavaScript 將 Math.random 指定為偽隨機來源,但不需要密碼抵抗預測。它適合的工作包括模擬、遊戲和洗牌。一旦標識符可以影響存取、物件發現或其他對抗性決策,外觀就不再是證據。發電機的書面合約比一頁看似合理的輸出更重要。
Inside Math.random — 一種具有固定內部狀態的種子偽隨機演演算法,專為速度和統計傳播而不是保密而設計
由於 Math.random 未指定為加密產生器,因此不得將其輸出視為未來值對觀察者隱藏的證據。 crypto.getRandomValues 有一個不同的平台契約:它用加密強值填滿整數類型陣列。 Web 加密規範將確切的產生器留給使用者代理,因此應用程式程式碼不應宣告特定的演演算法、種子大小或熵裝置。 ToolAcre 僅需要支援的邊界:瀏覽器提供安全隨機字節,JavaScript 接收填充的 Uint8Array,並 UUID 程式碼設定版本和變體欄位。該語句在內部實作不同的瀏覽器之間既有用又可移植。
為什麼觀察輸出可以揭示狀態——一個小狀態如何意味著一系列值可以讓某人預測下一個值
應用程式程式碼從 getRandomValues 接收加密強值,而不是實作或公開 JavaScript PRNG 狀態。安全差異在實際系統中顯現出來。從 Math.random 建構的識別碼在預測會產生後果的情況下是不合適的,因為能夠讀取網路(或任何先前 UUID 可見的系統)的攻擊者可以預測下一個。來自 crypto.getRandomValues 的 v4 UUID 本身並不是身份驗證令牌(您仍然需要過期、散列、速率限制),但產生器旨在抵抗預測。如果不存在安全來源,ToolAcre 將拒絕產生標識符,而不是默默地降級為可預測的公式。 Math.random 在主要引擎中附帶了微妙的分發錯誤。輸出序列看起來可能有所不同,但沒有提供秘密承載角色所需的對抗性不可預測性。
在 crypto.getRandomValues 內部 - 瀏覽器詢問操作系統的 CSPRNG,它混合了硬體和系統熵,並被設計為不可預測
特定於引擎的演演算法及其統計行為可能會發生變化;無論是目視檢查還是隨機分佈測試都無法將 Math.random 升級為加密來源。碰撞計算也假設來自指定空間的獨立輸出。如果產生器重複狀態、種子錯誤或被確定性固定裝置替換,則該假設失敗,且公式不再描述實作。這兩個 API 都可以產生看起來一樣不規則的字串。威脅模型將它們分開:必須抵抗預測的值使用 crypto.getRandomValues,而模擬和非對抗性洗牌可能使用 Math.random。選擇是根據預測的結果,而不是根據標點符號或樣本中的明顯變化。
工作範例 - 使用每種方法產生相同數量的識別碼並比較觀察者可以推斷出的內容
ToolAcre UUID 產生器專門使用 crypto.getRandomValues;它從不使用 Math.random,因為可預測的 UUID 的成本總是高於稍慢的產生器的成本。加密差異可以透過威脅模型來衡量。想要偽造 UUID 的攻擊者必須直接猜測識別符或破壞隨機數產生器。直接猜測不是本文量化的比較;支持的結論是 Web Crypto 旨在實現加密隨機性,而 Math.random 則不是。 CSPRNG 和 Math.random 公開了不同的合約:前者是為安全敏感的隨機性而設計的,而後者則沒有這樣的承諾。使用 Math.random 作為識別符的系統已經失去了加密屬性;現在的安全性取決於對產生的 UUID 序列進行保密。即使有一個 UUID 洩漏,整個下一代都會受到損害。
歷史性的分發錯誤 - 提醒引擎已經提供了具有明顯不均勻輸出的 Math.random 實現,並進行了定性描述
如果應用程式將 UUID 儲存在日誌、資料庫或版本控制歷史記錄中,則洩漏幾乎是不可避免的。 ToolAcre 函式庫強制使用 crypto.getRandomValues,並在安全性上下文(HTTPS 或 localhost)不可用時拒絕產生 UUID。這種設計決策可以防止靜默回退到困擾許多手動實現的 Math.random。在 Node.js 中,該程式庫使用 crypto 模組;在瀏覽器中,它使用 Web Crypto API。兩種支援的路徑都要求平台具有加密的強隨機性。此實作沒有提出任何效能要求,因為引擎、裝置和工作負載決定了時序;安全性合約是標識符的決定性屬性。為什麼業界標準決定採用 crypto.getRandomValues 是 UUID 濫用的簡短歷史。早期系統使用系統時間、網路介面和硬體時鐘來產生標識符。
這不包括任何模擬產生器的統計品質,這是與不可預測性不同的問題
基於時間、基於節點和隨機 UUID 版本解決不同的分配問題;不應將其呈現為對每個早期設計的線性修復。對於版本 4,RFC 9562 定義了隨機欄位並單獨討論了不可猜測性。因此,從 Math.random 的遷移會改變新產生的值的品質,而不會改變文字 UUID 形狀。現有標識符仍然是資料庫密鑰;重新產生它們會破壞引用。新值可以立即使用 Web Crypto,而授權必須繼續將每個舊的或新的 UUID 視為識別碼而不是權限證明。記錄截止時間,以便事件回應人員知道哪個發電機產生了每個族群。
重點:根據威脅而不是外觀來選擇產生器 — ToolAcre UUID 產生器專門使用 CSPRNG,從不使用 Math.random()
驗證應區分舊 ID(不適合保密)和新 ID(CSPRNG 支援)。檔案應記錄這種轉變。 ToolAcre 產生器僅產生 crypto.getRandomValues UUID;它不會嘗試驗證或重新產生來自其他來源的識別碼。 ToolAcre 產生器透過拒絕降級到較弱的隨機來源來展示最佳實踐。如果 crypto.getRandomValues 不可用,工具會報告錯誤,而不是默默地使用 Math.random。這項設計原則適用於任何安全關鍵系統:大聲失敗而不是在安全保障較弱的情況下悄悄成功。看到「UUID 產生失敗:加密 API 不可用」的開發人員必須解決根本問題(升級到 HTTPS、修復安全上下文或提供適當的後備)。默默接收從 Math.random 建置的 UUID 的開發人員並沒有跡象表明系統已受到損害。 ToolAcre 庫優先考慮誠實而不是方便。