當前位置:
首頁 > 最新 > 如何安全地生成隨機數

如何安全地生成隨機數

太長了,懶得看:直接使用 urandom 吧。

-- Thomas & Erin Ptacek

致謝

編譯自 | https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/

作者 | 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,因為:

內核可以訪問原始設備熵。

它可以確保不在應用程序之間共享相同的狀態。

一個好的內核 CSPRNG,像 FreeBSD 中的,也可以保證它播種之前不給你隨機數據。

研究過去十年中的隨機失敗案例,你會看到一連串的用戶空間的隨機失敗案例。Debian 的 OpenSSH 崩潰

[7]

?用戶空間隨機!安卓的比特幣錢包重複 ECDSA 隨機 k 值

[8]

?用戶空間隨機!可預測洗牌的賭博網站?用戶空間隨機!

用戶空間的生成器幾乎總是依賴於內核的生成器。即使它們不這樣做,整個系統的安全性也會確保如此。但用戶空間的 CSPRNG 不會增加防禦深度;相反,它會產生兩個單點故障。

手冊頁不是說使用 /dev/random 嘛?

這個稍後詳述,保留你的意見。你應該忽略掉手冊頁。不要使用 。 和 之間的區別是 Unix 設計缺陷。手冊頁不想承認這一點,因此它產生了一個並不存在的安全顧慮。把 中的密碼學上的建議當作傳說,繼續你的生活吧。

但是如果我需要的是真隨機值,而非偽隨機值呢?

urandom 和 提供的是同一類型的隨機。與流行的觀念相反, 不提供「真正的隨機」。從密碼學上來說,你通常不需要「真正的隨機」。

urandom 和 都基於一個簡單的想法。它們的設計與流密碼的設計密切相關:一個小秘密被延伸到不可預測值的不確定流中。 這裡的秘密是「熵」,而流是「輸出」。

只在 Linux 上 和 urandom 仍然有意義上的不同。Linux 內核的 CSPRNG 定期進行密鑰更新(通過收集更多的熵)。但是 也試圖跟蹤內核池中剩餘的熵,並且如果它沒有足夠的剩餘熵時,偶爾也會罷工。這種設計和我所說的一樣蠢;這與基於「密鑰流」中剩下多少「密鑰」的 AES-CTR 設計類似。

如果你使用 而非 urandom,那麼當 Linux 對自己的 RNG(隨機數生成器)如何工作感到困惑時,你的程序將不可預測地(或者如果你是攻擊者,非常可預測地)掛起。使用 會使你的程序不太穩定,但這不會讓你在密碼學上更安全。

這是個缺陷,對嗎?

不是,但存在一個你可能想要了解的 Linux 內核 bug,即使這並不能改變你應該使用哪一個 RNG。

在 Linux 上,如果你的軟體在引導時立即運行,或者這個操作系統你剛剛安裝好,那麼你的代碼可能會與 RNG 發生競爭。這很糟糕,因為如果你贏了競爭,那麼你可能會在一段時間內從 urandom 獲得可預測的輸出。這是 Linux 中的一個 bug,如果你正在為 Linux 嵌入式設備構建平台級代碼,那你需要了解它。

在 Linux 上,這確實是 urandom(而不是 )的問題。這也是Linux 內核中的錯誤

[9]

。 但它也容易在用戶空間中修復:在引導時,明確地為 urandom 提供種子。長期以來,大多數 Linux 發行版都是這麼做的。但不要切換到不同的 CSPRNG。

在其它操作系統上呢?

FreeBSD 和 OS X 消除了 urandom 和 之間的區別;這兩個設備的行為是相同的。不幸的是,手冊頁在解釋為什麼這樣做上乾的很糟糕,並延續了 Linux 上 urandom 可怕的神話。

無論你使用 還是 urandom,FreeBSD 的內核加密 RNG 都不會停擺。 除非它沒有被提供種子,在這種情況下,這兩者都會停擺。與 Linux 不同,這種行為是有道理的。Linux 應該採用它。但是,如果你是一名應用程序開發人員,這對你幾乎沒有什麼影響:Linux、FreeBSD、iOS,無論什麼:使用 urandom 吧。

太長了,懶得看

直接使用 urandom 吧。

結語

ruby-trunk Feature #9569

[10]

現在,在嘗試檢測 之前,SecureRandom.random_bytes 會嘗試檢測要使用的 OpenSSL。 我認為這應該反過來。在這兩種情況下,你只需要將隨機位元組進行解壓,所以 SecureRandom 可以跳過中間人(和第二個故障點),如果可用的話可以直接與 進行交互。

總結:

不適合用來直接生成會話密鑰和頻繁生成其他應用程序級隨機數據。

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中國榮譽推出

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Linux中國 的精彩文章:

哪個 Linux 內核版本是 「穩定的」?
Linux 中的「大內存頁」是個什麼?

TAG:Linux中國 |