libsodium 初始化的熵計數 (RNDGETENTCNT) 為 160 有什麼特別之處?
(從 StackOverflow 移出)
在libsodium的使用
sodium_init
文件中,在呼叫初始化函式之前,他們建議您檢查系統的 CSPRNG 的熵計數(即用於ioctl
查詢RNDGETENTCNT
)。那講得通。在範常式式碼中,他們檢查熵是否至少為 160。160值有什麼特別之處?
Linux CSPRNG 現在使用的是 ChaCha20,對吧?但我認為這需要初始化超過 160 位的隨機性(例如,它看起來像最近核心中的
getrandom
系統呼叫塊,直到它獲得至少兩倍於 ChaCha20 密鑰長度的隨機性,即 512 位)。
[更新:查看軟體作者的真實原因弗蘭克丹尼斯的回答,這與 sodium_init 是否會阻塞有關,而不是系統的安全性。我保留下面的答案,以討論與數字 160 相關的安全分析。]
等待系統熵池播種的標準方法是從 /dev/random 讀取單個字節。這在 Linux 中有效,並且已經在幾乎所有作業系統上工作了數十年,並且不需要花哨的 Linux 特定 ioctls——如果您希望您的應用程序能夠在啟動時處理等待,它可以確保您實際上是測試阻塞程式碼路徑,因為 /dev/random 可以隨時阻塞,並且不會限制自己在啟動時阻塞一次,當您可能在將程式碼部署到現場之前可能不會測試程式碼時。
充其量,該
RNDGETENTCNT
測試有助於區分完全損壞的環境,例如沒有從主機連接熵源的 VM(例如virtio-rng)和未完全損壞的環境。
- 如果您有一個真正的熵源或從一個派生的啟動時間種子,那麼在啟動時熵應該至少為 256 位。
- 如果您在虛擬化系統上什麼都沒有,沒有發生很多中斷,也沒有任何磁碟 I/O 等,那麼熵可能會非常接近 0。在這種情況下,您可以發出警報。
它不會幫助您區分安全環境和不安全環境。
- 如果您發生了一些中斷和一些輸入,但沒有嚴重的 RNG 或種子,則虛假熵估計器將為您提供一些可能高於或低於 160 位的虛假數字。也許系統處於不可預測的狀態;也許不是。系統無法區分人類不可預測地打字的中斷時間和精心定時猛攻網路數據包以欺騙熵估計器的中斷時間之間的區別。
由您來安排系統工程以確保安全性:例如,確保您有一個硬體 RNG,或確保您的 VM 已連接到主機的硬體 RNG,或確保您使用 512 次公平的硬幣投擲來為您的池播種沒有相機對准你。(為什麼是 512?也許你的硬幣拋擲不均勻,但接近它。
那麼160是什麼數字呢? 我不知道,從上述推理來看,我認為這並沒有多大意義,但這是我的猜測。假設您的目標是“128 位安全級別”。天真的解釋是,這需要對手對你的系統的知識狀態有 128 位熵,或者接近它。
如果你從表面上看假熵估計器,那麼 160 位就是 128 加上一個保守的斜率:如果我們使用 128 位輸入,並將其散列到 128 位輸出,那麼只有大約 $ 2^{128} (1 - e^{-1}) \approx 2^{127.34} $ 預期可能的結果,損失了幾乎一點熵。NIST 建議以下因素 $ 2^{128} $ 不小於 $ 1 - 2^{-64} $ 在 SP800-90C 中。相比之下,將 160 位輸入散列到 128 位輸出,得到大約 $ 2^{128} (1 - e^{-2^{32}}) $ 預期的可能結果。( $ e^{-2^{32}} $ 即使與 $ 2^{-64} $ .)
然而,這只是對“128 位安全級別”的幼稚解釋。熵實際上是成功攻擊成本的代表。天真的解釋是,當有 $ 2^{128} $ 對手必須通過蠻力嘗試的等機率可能性,則預期成本為 $ 2^{127} $ 試煉,這是任何對手都無法嘗試的。但在實踐中,攻擊者對攻擊眾多使用者中的一個感興趣:攻擊網路中的一個使用者,而您可能有一個立足點來攻擊網路中的其他使用者。
對於第一個的通用原像搜尋 $ t $ 目標之間 $ n $ 可能性,例如找到任何一個使用的 AES 密鑰 $ t $ 使用者,預期成本為 $ O(n/t) $ . 對於通用離散日誌搜尋,例如在其中查找 X25519 鍵 $ n $ 可能性,它是不同的: $ O(\sqrt n) $ 對於第一個 $ t $ 使用者, $ O(\sqrt{n t}) $ 對於所有_ $ t $ 使用者。這就是為什麼如果 X25519 具有 128 位安全級別,那麼 AES-128 的安全級別遠低於128 位安全級別。
確保恢復密鑰的成本接近 $ 2^{128} $ 即使您擁有與當今地球上的人類一樣多的使用者,您也可以確保有 $ 2^{160} $ 對手必須考慮的可能性。 就我個人而言,我認為這個數字有點保守——不難想像一個應用程序擁有比地球上人類更多的密鑰——並且更喜歡通過例如散列 512 大部分公平硬幣來瞄準池中的 256 位熵扔進去。
PS
RNDGETENTCNT
本身有點傻:它充當進入熵池的原始數據的側通道,因為它的增量是由核心的熵估計器根據原始數據計算的。這甚至可以用作例如操作員鍵入的擊鍵之間的持續時間的側通道。當然,這不是您可以在應用程序中解決的問題,除非拒絕公開RNDGETENTCNT
應用程序的輸出。