作者 | Thomas & Erin Ptacek
譯者 | kimii ? ? 共計翻譯:8 篇 貢獻時間:117 天
使用 urandom
使用 urandom[1]!使用 urandom[2]!使用 urandom[3]!
使用 urandom[4]!使用 urandom[5]!使用 urandom[6]!
但對於密碼學金鑰呢?
仍然使用 urandom[6]。
為什麼不是 SecureRandom、OpenSSL、havaged 或者 c 語言實現呢?
這些是使用者空間的 CSPRNG(偽隨機數生成器)。你應該用內核的 CSPRNG,因為:
研究過去十年中的隨機失敗案例,你會看到一連串的使用者空間的隨機失敗案例。Debian 的 OpenSSH 崩潰[7]?使用者空間隨機!安卓的比特幣錢包重覆 ECDSA 隨機 k 值[8]?使用者空間隨機!可預測洗牌的賭博網站?使用者空間隨機!
使用者空間的生成器幾乎總是依賴於內核的生成器。即使它們不這樣做,整個系統的安全性也會確保如此。但使用者空間的 CSPRNG 不會增加防禦深度;相反,它會產生兩個單點故障。
手冊頁不是說使用 /dev/random 嘛?
這個稍後詳述,保留你的意見。你應該忽略掉手冊頁。不要使用 /dev/random
。/dev/random
和 /dev/urandom
之間的區別是 Unix 設計缺陷。手冊頁不想承認這一點,因此它產生了一個並不存在的安全顧慮。把 random(4)
中的密碼學上的建議當作傳說,繼續你的生活吧。
但是如果我需要的是真隨機值,而非偽隨機值呢?
urandom 和 /dev/random
提供的是同一型別的隨機。與流行的觀念相反,/dev/random
不提供“真正的隨機”。從密碼學上來說,你通常不需要“真正的隨機”。
urandom 和 /dev/random
都基於一個簡單的想法。它們的設計與流密碼的設計密切相關:一個小秘密被延伸到不可預測值的不確定流中。 這裡的秘密是“熵”,而流是“輸出”。
只在 Linux 上 /dev/random
和 urandom 仍然有意義上的不同。Linux 內核的 CSPRNG 定期進行金鑰更新(透過收集更多的熵)。但是 /dev/random
也試圖跟蹤核心池中剩餘的熵,並且如果它沒有足夠的剩餘熵時,偶爾也會罷工。這種設計和我所說的一樣蠢;這與基於“金鑰流”中剩下多少“金鑰”的 AES-CTR 設計類似。
如果你使用 /dev/random
而非 urandom,那麼當 Linux 對自己的 RNG(隨機數生成器)如何工作感到困惑時,你的程式將不可預測地(或者如果你是攻擊者,非常可預測地)掛起。使用 /dev/random
會使你的程式不太穩定,但這不會讓你在密碼學上更安全。
這是個缺陷,對嗎?
不是,但存在一個你可能想要瞭解的 Linux 核心 bug,即使這並不能改變你應該使用哪一個 RNG。
在 Linux 上,如果你的軟體在引導時立即執行,或者這個作業系統你剛剛安裝好,那麼你的程式碼可能會與 RNG 發生競爭。這很糟糕,因為如果你贏了競爭,那麼你可能會在一段時間內從 urandom 獲得可預測的輸出。這是 Linux 中的一個 bug,如果你正在為 Linux 嵌入式裝置構建平臺級程式碼,那你需要瞭解它。
在 Linux 上,這確實是 urandom(而不是 /dev/random
)的問題。這也是 Linux 核心中的錯誤[9]。 但它也容易在使用者空間中修複:在引導時,明確地為 urandom 提供種子。長期以來,大多數 Linux 發行版都是這麼做的。但不要切換到不同的 CSPRNG。
在其它作業系統上呢?
FreeBSD 和 OS X 消除了 urandom 和 /dev/random
之間的區別;這兩個裝置的行為是相同的。不幸的是,手冊頁在解釋為什麼這樣做上乾的很糟糕,並延續了 Linux 上 urandom 可怕的神話。
無論你使用 /dev/random
還是 urandom,FreeBSD 的核心加密 RNG 都不會停擺。 除非它沒有被提供種子,在這種情況下,這兩者都會停擺。與 Linux 不同,這種行為是有道理的。Linux 應該採用它。但是,如果你是一名應用程式開發人員,這對你幾乎沒有什麼影響:Linux、FreeBSD、iOS,無論什麼:使用 urandom 吧。
太長了,懶得看
直接使用 urandom 吧。
結語
ruby-trunk Feature #9569[10]
現在,在嘗試檢測
/dev/urandom
之前,SecureRandom.random_bytes 會嘗試檢測要使用的 OpenSSL。 我認為這應該反過來。在這兩種情況下,你只需要將隨機位元組進行解壓,所以 SecureRandom 可以跳過中間人(和第二個故障點),如果可用的話可以直接與/dev/urandom
進行互動。
總結:
/dev/urandom
不適合用來直接生成會話金鑰和頻繁生成其他應用程式級隨機資料。GNU/Linux 上的 random(4) 手冊所述……
感謝 Matthew Green、 Nate Lawson、 Sean Devlin、 Coda Hale 和 Alex Balducci 閱讀了本文草稿。公正警告:Matthew 只是大多同意我的觀點。
via: https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
作者:Thomas & Erin Ptacek[12] 譯者:kimii 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出