[翻譯] Java 各種亂數產生器的弱點
原文網址:http://www.javacodegeeks.com/2013/03/
weaknesses-in-java-pseudo-random-number-generators-prngs.html
譯文網址:http://blog.dontcareabout.us/2013/03/java-prng.html
BBS 版以 markdown 格式撰寫
______________________________________________________________________
這是 Kai Michaelis、Jorg Schwenk 還有我在 [RA Conference 2013] 的
Cryptographers' Track 發表論文的總結。
你可以取得我演講時的[投影片]、還有[論文全文]。
我們對常見 Java library 所產生的亂數序列進行分析,
這些 Java library 用了 PRNG
(Pseudo Random Number Generator,通常是 SecureRandom),
我們發現在特定條件下有明顯的弱點。
為了讓這篇文章盡可能簡短,各種 PRNG 所用的演算法、詳細的 bug 描述、
統計檢驗的結果都略過不提,但是論文裡頭都有。
我們的調查涵蓋 PRNG 本身、以及它們用來作 seed 的 entropy collector
(例如沒有可用的實數產生器時)。
**底線:需要品質良好的亂數時,不要使用 PRNG!**
[RA Conference 2013]: https://ae.rsaconference.com/US13/connect/
sessionDetail.ww?SESSION_ID=3386&tclass=popup
[投影片]: https://ae.rsaconference.com/US13/connect/fileDownload/
session/85EEC4CC0848A5E7793DDEC27550D7A6/CRYP-W25.pdf
[論文全文]: http://link.springer.com/chapter/10.1007%2F978-3-642-36095-4_9
有很多測量品質的方式。首先,我們分析程式碼,
然後試圖(且成功地)發現導致缺陷的明顯程式錯誤。
再者,我們對產生出來的亂數序列進行統計檢驗。
最後,我們在特定情況下(高系統負載、某些 component 無法使用...... 等等)
對演算法作壓力測試。
[Apache Harmony]
================
雖然已經退休了(譯註:原文是 although retried,應該是 typo),
但是 Apache Harmony 仍然活在 Android source code 中
(參見[這裡][Harmony Wikipedia])、
是幾百萬台機器的一部分。
[Apache Harmony]: http://harmony.apache.org/
[Harmony Wikipedia]: http://en.wikipedia.org/wiki/
Apache_Harmony#Use_in_Android_SDK
弱點
----
其中一個發現的 bug 直接影響 Android 平台。
其餘的 bug 只在 Apache Harmony 當中,
「並沒有」出現在 Android source code 裡頭。
1. 當建立一個自己提供 seed 的 SecureRandom instance
(呼叫沒有參數的 constructor 以及後續呼叫 `setSeed()`),
在插入起始值之後,程式碼無法調整 byte offset
(在 state buffer 中的 pointer)。
這導致 counter 跟一開始的 padding(一個 32 bit word)
覆蓋掉 seed 的一部分、而不是加在後頭。
2. 當在 Unix-like 的 OS 下執行時,
新的 SecureRandom instance 給的 seed 是 20 byte、
來自 urandom 或是 random device。
如果兩個 device 都無法存取,這個實作會提供一個備援的 seed 工具。
一旦這個 seed 工具已經收集到需要的 byte 數,
因為不明原因 most significant bit 會設定為 0。
結果就是 SecureRandom instance 的有效 seed 中,
每個 byte 只有 7/8,少了 8bit 而只剩下 56bit 的安全性
(因為第一個 bug 的關係,所以全部只有 64 bit)。
更糟的是,由於其他有問題的 modulo reduction,
單一呼叫 seed 工具的 entropy 被限制為 31 bit。
當觀察產生出來的 byte 時,entropy collector 的問題是顯而易見的。
下面這張圖將兩個 consecutive byte 標為一個點:
![Harmony image](http://cdn.javacodegeeks.com/wp-content/uploads/
2013/03/harmony-seed.png)
兩個方向都缺乏大於 127 的數字。
GNU Classpath
=============
在有名的 [IcedTea] project 中有用到一部分的 GNU Classpath,
最為人知的是 Linux 上的 64-bit Java browser plugin。
[GNU Claspath]: http://www.gnu.org/software/classpath/
[IcedTea]: http://icedtea.classpath.org/wiki/Main_Page
弱點
----
這個 library 包含了一個關於 internal state 的明顯弱點。
這個 bug 是關於在 hash 函數中使用相同的 Initialization Vector(IV)。
這減少了 internal state 未知的 byte 數量,
從 32 減少到只有 20。
entropy collector 演算法很難預測,這樣很好,
但是它倚賴 thread 之間競爭 CPU 時間的行為,
要影響這個行為很容易(透過讓系統處於高負載的情況下)。
thread 在執行期檢查不夠嚴格、無法確保良好的隨機性。
下面的圖表顯示要輸出平均分佈是有困難的,留下了大片的斑點。
這張圖是在系統高負載的情況下 entropy collector 執行的結果:
![GNU image1](http://cdn.javacodegeeks.com/wp-content/uploads/
2013/03/classpath-seed.png)
相反地,在正常條件下會是這樣:
![GNU image2](http://cdn.javacodegeeks.com/wp-content/uploads/
2013/03/classpath-seednormal.png)
[OpenJDK]
=======
官方免費 open source 的 JavaSE 實作,
大抵上等同於 Oracle 提供的版本。
大多數的 Java 使用者可能都是用這份程式碼。
[OpenJDK]: http://openjdk.java.net/
弱點
----
code review 沒有找出什麼明顯的弱點。
entropy collector 倚賴 thread 遞增計數器,
但是有別於 GNU Classpath,它會確保執行時間的最小值。
得到的結果圖形被很均勻地填滿。
![OpenJDK image](http://cdn.javacodegeeks.com/wp-content/uploads/
2013/03/openjdk-seed.png)
[The Legion of Bouncy Castle]
=============================
以某些角度來看,這個 library 跟其他的不太一樣,
因為它只是一個非常綜合性的加密演算法 library。
它有多個 SecureRandom 的替代品。
BouncyCastle 的 entropy collector 可以在兩種模式下運作:
快速模式與慢速模式,`random` 輸出會使用不同的 byte 數。
[The Legion of Bouncy Castle]: http://www.bouncycastle.org/java.html
弱點
----
跟 OpenJDK 相同,Bouncy Castle 的 SecureRandom 替代品
(DigestRandomGenerator)也沒有什麼明顯的 bug。
相反地 VMPCRandomGenerator 已知是有弱點的。
entropy collector 在兩種模式下都可以把圖形填滿的很均勻。
快速模式的圖:
![BC fast mode](http://cdn.javacodegeeks.com/wp-content/uploads/
2013/03/bcfast-seed.png)
慢速模式的圖:
![BC slow mode](http://cdn.javacodegeeks.com/wp-content/uploads/
2013/03/bcslow-seed.png)
總結
====
上頭這些實作的限制、不可設定的 internal state 是十分有趣的。
幾乎所有實作都靠 SHA-1 作為 hash 函數。
因此,在 key 產生器大於 160 bit 時似乎沒啥用處。
只有 Apache Harmony 是用 512bit 的 internal state,
但是它的程式有問題。
blog 的文章省略了很多細節與統計數據,只是為了提供一個快速而簡單的評論。
如果你有興趣知道更詳細的內容,麻煩請去讀完整的論文。
______________________________________________________________________
譯註:說真的,翻完自己都看不懂,還是去看原始論文吧 Orz
--
錢鍾書: 說出來的話
http://www.psmonkey.org
比不上不說出來的話
Java 版 cookcomic 版
只影射著說不出來的話
and more......
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.25.4.190
※ 編輯: PsMonkey 來自: 114.25.15.134 (03/31 11:29)
Translate-CS 近期熱門文章
PTT數位生活區 即時熱門文章