Linux中國

如何安全地生成隨機數

使用 urandom

使用 urandom!使用 urandom!使用 urandom

使用 urandom!使用 urandom!使用 urandom

但對於密碼學密鑰呢?

仍然使用 urandom

為什麼不是 SecureRandom、OpenSSL、havaged 或者 c 語言實現呢?

這些是用戶空間的 CSPRNG(偽隨機數生成器)。你應該用內核的 CSPRNG,因為:

  • 內核可以訪問原始設備熵。
  • 它可以確保不在應用程序之間共享相同的狀態。
  • 一個好的內核 CSPRNG,像 FreeBSD 中的,也可以保證它播種之前不給你隨機數據。

研究過去十年中的隨機失敗案例,你會看到一連串的用戶空間的隨機失敗案例。Debian 的 OpenSSH 崩潰?用戶空間隨機!安卓的比特幣錢包重複 ECDSA 隨機 k 值?用戶空間隨機!可預測洗牌的賭博網站?用戶空間隨機!

用戶空間的生成器幾乎總是依賴於內核的生成器。即使它們不這樣做,整個系統的安全性也會確保如此。但用戶空間的 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 內核中的錯誤。 但它也容易在用戶空間中修復:在引導時,明確地為 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

現在,在嘗試檢測 /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 譯者:kimii 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國