劉 攀, 陳天宇, 馬 原, 吳鑫瑩, 呂 娜, 荊繼武
1. 中國科學院 信息工程研究所 信息安全國家重點實驗室, 北京100093
2. 中國科學院 數(shù)據(jù)與通信保護研究教育中心, 北京100093
3. 中國科學院大學 計算機科學與技術學院, 北京100049
通信作者: 陳天宇, E-mail: chentianyu@iie.ac.cn
隨機數(shù)發(fā)生器作為現(xiàn)代密碼學的基本原語之一, 其生成的隨機數(shù)具有廣泛的應用, 如用于對稱或非對稱密碼算法的密鑰產生、“挑戰(zhàn)-響應”協(xié)議方案中的一次性口令、電子簽名方案中的秘密信息,以及抵抗側信道分析攻擊等. 隨機數(shù)質量的好壞直接關系到密碼算法和協(xié)議等密碼應用的安全性. 如何產生高質量的隨機數(shù)一直是密碼學領域長期關注的研究問題[1-9]. 按產生原理的不同,隨機數(shù)發(fā)生器(Random Number Generator, RNG) 主要分為非確定性隨機數(shù)發(fā)生器(NDRNG) 和確定性發(fā)生器(DRNG). NDRNG 通常是采集來自于物理或非物理現(xiàn)象的隨機性, 如電子噪聲、電磁輻射、系統(tǒng)中斷、鼠標/鍵盤操作等, 進而通過數(shù)字化處理等環(huán)節(jié)生成具有良好不可預測性的數(shù)據(jù); 而DRNG 則是采用確定性算法將一段隨機序列(即“種子”, 一般由NDRNG 產生) 擴展成任意長度的序列. 按發(fā)生器形態(tài)分類, 又可分為硬件形態(tài)的隨機數(shù)發(fā)生器(硬件RNG) 和軟件形態(tài)的隨機數(shù)發(fā)生器(軟件RNG). 硬件RNG 通常在研制時需要投入較大的成本以實現(xiàn)生成高質量的隨機數(shù), 并且硬件形態(tài)的產品更新迭代周期長. 隨著智能移動終端、物聯(lián)網設備等便攜式設備的不斷普及, 以及軟件密碼模塊逐步興起和廣泛應用, 傳統(tǒng)的硬件RNG 已不能完全滿足當前的密碼應用對隨機數(shù)服務的需求[10]. 因此, 以軟件形式產生隨機數(shù)成為各類系統(tǒng)平臺中最為常見的方法. 不同于硬件RNG, 我們將諸如運行在Linux、Windows、Android、嵌入式操作系統(tǒng)等軟件平臺上以軟件形態(tài)呈現(xiàn)的隨機數(shù)發(fā)生器稱為軟件隨機數(shù)發(fā)生器(簡稱軟件RNG).
軟件RNG 目前已有許多較成熟的結構, 學者們對這些結構的原理以及安全性進行了大量深入的研究[7,11-16], 如何設計一個高質量的軟件RNG 一直是密碼學領域的研究重點. 一些研究工作為軟件RNG的設計給出了建議: Shamir 等人[1]在1983 年首次給出基于一個短的隨機種子生成偽隨機數(shù)的實例;Gutmann 等人[3]在1998 年給出了設計和實現(xiàn)一個隨機數(shù)發(fā)生器的較為全面的指南; 2005 年, Barak 等人[6]提出了一種穩(wěn)健的隨機數(shù)生成模型和架構. 此外, 一些研究工作針對典型操作系統(tǒng)平臺已有的軟件RNG 的結構和原理等進行了分析. Gutterman 等人[13]對Linux 內核中的隨機數(shù)發(fā)生器結構和安全性進行了深入分析, 給出了Linux 內核版本2.6.10 中的隨機數(shù)發(fā)生器結構, 并指出該版本的LRNG 無法完全滿足前向安全性等設計準則. 2013 年, Strenzke 等人[14]分析了Android 中OpenSSL 所使用的隨機數(shù)發(fā)生器. 針對Windows 操作系統(tǒng)的隨機數(shù)發(fā)生器, Dorrendorf 等人[15]對Windows 內核隨機數(shù)發(fā)生器CryptGenRandom 結構進行了分析, 隨后Alzhrani 等人在2015 年對Windows 內核的隨機數(shù)發(fā)生器BCryptGenRandom 結構進行了研究[16]. 對于iOS、Mac 和FreeBSD 等操作系統(tǒng), 它們早期采用由Kelsey 等人設計的Yarrow 隨機數(shù)發(fā)生器[7], 隨后Ferguson 和Schneier 團隊[17]對Yarrow 進行了改進, 提出Fortuna 隨機數(shù)發(fā)生器, 一些操作系統(tǒng)使用Fortuna 發(fā)生器取代了Yarrow 發(fā)生器, 如FreeBSD.綜上, 本文總結了幾種典型操作系統(tǒng)平臺上軟件RNG 的基本結構和產生原理, 并對隨機數(shù)生成機制進行了對比分析. 在此基礎上, 進一步梳理了軟件RNG 安全性分析的關注點.
本文的組織結構如下: 第2 節(jié)概述了軟件RNG 的相關知識, 包括軟件RNG 基本模型、安全性要求以及隨機數(shù)發(fā)生器安全性測試方法; 第3 節(jié)介紹了典型操作系統(tǒng)平臺上軟件RNG 的結構和工作原理; 第4 節(jié)梳理了軟件RNG 安全性分析關注點; 第5 節(jié)對本文研究工作進行總結.
軟件RNG 的基本結構模型. 通常來講, 基于外部熵源的軟件RNG 的基本結構如圖1 所示, 主要包括熵源、處理函數(shù)、內部狀態(tài)和輸出函數(shù). 熵源通過處理函數(shù)產生內部狀態(tài), 通過控制條件(熵值充足的閾值、數(shù)據(jù)長度要求的閾值等) 執(zhí)行種子更新(重播種函數(shù)), 進而完成內部狀態(tài)的更新, 再由輸出函數(shù)產生隨機數(shù)據(jù). 其中:
· 熵源: 提供隨機性的來源, 又可分為兩類: 基于操作系統(tǒng)平臺的時鐘生成種子和外部隨機源提供種子, 外部隨機源有鼠標/鍵盤的操作、網絡中斷、磁盤讀寫或NDRNG 提供的隨機數(shù)等.
· 處理函數(shù): 用于熵累積和更新內部狀態(tài), 包括熵累積函數(shù)、播種(seed) 函數(shù)和重播種(reseed) 函數(shù).
· 內部狀態(tài): 用于存儲軟件RNG 使用或產生用途的所有參數(shù)、變量和其他存儲值, 包括管理數(shù)據(jù)(如安全性參數(shù)), 以及在運行期間產生或修改的數(shù)據(jù).
· 輸出函數(shù): 用于對內部狀態(tài)處理以生成隨機數(shù),常使用確定性密碼算法實現(xiàn),目前的軟件RNG 中使用的輸出函數(shù)有基于CTR 模式的分組密碼算法、密碼雜湊算法等.
圖1 基于外部熵源的軟件RNG 基本結構Figure 1 Basic structure of software RNG based on external entropy sources
隨機數(shù)發(fā)生器設計的安全性要求. 對于一個安全的系統(tǒng)而言, 如果無法獲取高質量的隨機序列, 那么可能會導致致命的安全性風險. 對于一個軟件形式的隨機數(shù)發(fā)生器而言, 攻擊者被假定已知隨機數(shù)發(fā)生器的所有源程序代碼, 并且可能通過一些手段, 了解隨機數(shù)發(fā)生器部分內部狀態(tài)的更新情況. 一些標準[18]或研究工作[6,19]針對軟件RNG 的安全性要求進行探究, 認為設計出來的軟件RNG 需要滿足以下安全性要求:
(1) 偽隨機性: 對于一個對發(fā)生器內部狀態(tài)一無所知的觀測者而言, 發(fā)生器的輸出應該是看上去隨機的, 即便觀測者完全控制了用于更新內部狀態(tài)的數(shù)據(jù), 上述結論應仍保持不變;
(2) 前向安全性: 對于一個攻擊者而言, 即便他獲取了發(fā)生器在某一特定時刻的狀態(tài), 也不能獲知在此之前任意時刻的輸出;
(3) 后向安全性: 對于一個攻擊者而言, 即便他獲取了發(fā)生器在某一特定時刻的狀態(tài), 也不能獲知在此之后任意時刻的輸出;
(4) 健全的熵估計: 發(fā)生器能夠正確估計是否已收集到足夠的熵, 以確保觀測不到輸入的攻擊者無法有效地猜測輸出.
美國國家標準與技術研究院(NIST) 在SP800-90A[18]標準中對發(fā)生器如何滿足前向/后向安全性給出了建議: 在生成隨機數(shù)的過程中通過使用具有單向性的函數(shù)可以保證前向安全性; 而后向安全性僅能通過使用足夠的熵更新內部狀態(tài)來實現(xiàn).
隨機數(shù)發(fā)生器的檢測技術. 安全性檢測對于發(fā)生器整個生命周期而言是必不可少的. 目前, 安全性檢測方法大致可分為三類: 統(tǒng)計性質測試、理論熵估計和統(tǒng)計熵估計.
統(tǒng)計性質測試的目的是檢查隨機數(shù)發(fā)生器的輸出序列是否存在明顯的統(tǒng)計缺陷, 屬于較為傳統(tǒng)的黑盒測試. 由于這類測試并不關注隨機數(shù)生成原理和發(fā)生器內部結構, 而是只檢測輸出序列的統(tǒng)計性質好壞, 因此具有很好的通用性和可操作性, 但無法對不可預測性進行有效測量. 目前, 典型的統(tǒng)計測試方法有NIST 發(fā)布的SP800-22 標準[20]、L’Ecuyer 和Simard 提出的TestU01[21]、佛羅里達州立大學Marsaglia提出的Diehard 測試[22]、德國信息安全部門BSI 的AIS 20/AIS 31[23]標準以及我國發(fā)布的國家標準GB/T 32915-2016《信息安全技術 二元序列隨機性檢測方法》[24].
理論熵估計從隨機數(shù)發(fā)生器的結構和工作原理出發(fā), 建立一套基于數(shù)學建模的白盒檢測方法. 相比于基于統(tǒng)計性質的黑盒測試, 理論熵估計是通過數(shù)學建模的方式對特定結構發(fā)生器的工作原理進行刻畫, 然后通過熵計算來量化發(fā)生器輸出所含有的隨機性大小. 目前, 理論熵估計方法的研究尚集中在通用基礎結構上, 如振蕩采樣結構. 對該結構的熵估計研究主要圍繞兩個角度: 基于時間演變[25-27]和基于相位演變[28-30], 而二者在實質上是具有等價性的, 只是衡量方法不同. 不過, 理論熵估計方法由于屬于白盒測試,對于特定結構建立的模型的適用性十分有限, 并且有些發(fā)生器結構尚未發(fā)現(xiàn)有合適的建模方法, 如基于混沌的NDRNG[31-33].
統(tǒng)計熵估計介于白盒測試和黑盒統(tǒng)計測試之間, 既遵從了利用“熵” 來量化輸出序列隨機性的檢測理念, 又采用統(tǒng)計測試方式使得測試過程通用化、簡潔化. 目前, 這類測試方法中的典型是NIST SP800-90B(簡稱90B) 標準[34], 對于非獨立同分布的數(shù)據(jù)而言, 90B 包含10 個計算待測序列隨機性(熵) 的熵估計器. 待測數(shù)據(jù)的熵是取10 個熵估計器計算結果的最小值. 當待測試熵源的統(tǒng)計性質(比如周期性) 符合或近似90B 測試包中某一項檢測的預期時, 則通過90B 檢測可以得到較為準確的熵估計結果.
軟件形式的隨機數(shù)發(fā)生器廣泛應用于PC 平臺和移動終端平臺. 下面, 將對Linux、Android、Windows、iOS 等典型操作系統(tǒng)平臺的軟件隨機數(shù)發(fā)生器的基本結構和原理進行介紹, 并對它們的實現(xiàn)機制進行對比分析.
Linux 是目前最流行的開源項目之一, Linux 操作系統(tǒng)的隨機數(shù)發(fā)生器(LRNG) 是所有Linux 發(fā)行版內核的一部分. LRNG 最早由Theodore Ts’o 在1994 年設計實現(xiàn), 其設計思想是基于操作系統(tǒng)事件的隨機性來生成隨機數(shù), 它的輸出幾乎用于所有的安全協(xié)議中, 如TLS/SSL 密鑰生成、TCP 的序列號生成、文件系統(tǒng)和電子郵件加密.
在2006 年, Gutterman 等人[13]開展了對LRNG 實現(xiàn)的分析(針對2004 年12 月24 日發(fā)布的Linux 內核2.6.10 版本), 并給出了該內核版本下LRNG 的通用架構(見圖2). LRNG 生成隨機數(shù)主要由三個異步過程組成: (1) 采集作為熵源的系統(tǒng)事件, 從內核內部的各種事件收集系統(tǒng)熵(圖2 中的C), 系統(tǒng)事件包括鼠標移動、鍵盤操作、磁盤I/O、中斷; (2)對采集到的熵源數(shù)據(jù)進行熵估計量化, 調用Add 函數(shù)將采集的熵增加到熵池中并更新熵池內部狀態(tài)(圖2 中的A); (3) 響應外部請求產生隨機數(shù), 調用Extract函數(shù)(圖2 中的E) 從熵池中提取熵并更新熵池內部狀態(tài). 上述三個過程使用的唯一非線性密碼運算是SHA-1 密碼雜湊算法. LRNG 的內部狀態(tài)保存在三個熵池中, 包括圖2 中的主熵池(大小為512 字節(jié))、阻塞熵池(大小為128 字節(jié)) 和非阻塞熵池(大小為128 字節(jié)), 每個熵池都有一個熵值計數(shù)器(計數(shù)器值的類型為整數(shù), 取值范圍為[0, 熵池大小]). 熵源事件經過量化和熵估計過程后, 會先將熵源數(shù)據(jù)加入主熵池; 當主熵池熵滿時, 將熵源數(shù)據(jù)加入阻塞熵池; 當阻塞熵池熵滿時, 再將熵源數(shù)據(jù)添加到主熵池, 按此順序循環(huán)將熵源數(shù)據(jù)添加入熵池. 對于這三個任意熵池, 當有數(shù)據(jù)加入時, 那么該熵池的熵值計數(shù)器值將相應的增加; 反之則減少.
根據(jù)圖2 所示, LRNG 提供了三個隨機數(shù)輸出接口, 包括/dev/random、/dev/urandom 和get_random_bytes(). 其中, get_random_bytes() 僅在內核內部可用, 并且總是會返回請求的隨機數(shù)據(jù); 而/dev/random 和/dev/urandom 是從用戶空間訪問, 即便是非授權的用戶. /dev/random 接口對外提供的隨機數(shù)來源于阻塞熵池數(shù)據(jù), 它輸出一個相對安全的隨機數(shù). 阻塞熵池每次在輸出隨機數(shù)之前, 會先檢查熵值計數(shù)器的值, 查看是否滿足輸出條件(即當前熵值不小于請求的隨機比特長度), 若不滿足, 則調用Extract 函數(shù)從主熵池提取新數(shù)據(jù); 如果提取失敗, 則阻塞/dev/random 的請求. /dev/urandom 接口對外提供的隨機數(shù)來自非阻塞熵池數(shù)據(jù), 從主熵池向非阻塞熵池傳輸數(shù)據(jù)的條件是主熵池數(shù)據(jù)的熵值至少為192 比特. 只要非阻塞熵池不為空, 那么/dev/urandom 可以持續(xù)向用戶提供請求的隨機數(shù)據(jù).
圖2 早期內核版本的Linux 隨機數(shù)發(fā)生器通用架構Figure 2 General architecture of Linux random number generator of early kernel version
下面對早期內核版本的LRNG 運行機制的關鍵環(huán)節(jié)進行介紹.
系統(tǒng)啟動階段: LRNG 在計算機關機時會激活一個腳本, 這個腳本從/dev/urandom 中讀取512 個字節(jié)數(shù)據(jù)并將其寫到一個種子文件中保存起來. 當系統(tǒng)再次啟動時, 腳本被重新激活, 把保存的512 字節(jié)數(shù)據(jù)再寫回到/dev/urandom. 通過這個操作, 使得關機和開機之間存在了一種延續(xù)性, 腳本文件的加入是為了確保Linux 啟動時LRNG 內部狀態(tài)的安全性.
熵采集: LRNG 采集四種熵源數(shù)據(jù), 分別為鼠標移動、鍵盤操作、硬盤I/O 操作和特殊中斷. 當熵源事件發(fā)生時, 系統(tǒng)會生成兩個32 比特字. 第一個字代表事件發(fā)生的時間; 第二個字代表事件類型, 通常是對鍵盤按鍵或鼠標移動等事件類型的編碼.
熵估計: LRNG 利用熵源事件發(fā)生的時間來計算熵值, 其具體步驟如下:
熵池更新以及隨機數(shù)輸出: 內核通過調用Add(pool,j,g) 函數(shù)來實現(xiàn)熵增加和熵池內部狀態(tài)更新.其中, pool 表示哪個熵池將會加入新熵,j是該熵池中當前位置的索引,g表示要加入熵池的數(shù)據(jù). LRNG通過調用Extract(pool, nbytes,j) 函數(shù)來提取隨機比特, 其中, pool 為待提取數(shù)據(jù)的熵池, nbytes 為要提取的隨機比特長度,j為當前熵池中位置的索引, 每輪循環(huán)輸出10 字節(jié). 當阻塞熵池和非阻塞熵池需要更新內部狀態(tài)時, 調用Extract 函數(shù)從主熵池提取數(shù)據(jù)加入到對應熵池中.
隨著Linux 操作系統(tǒng)計算環(huán)境的變化和技術的演變, LRNG 在Linux 內核版本4.8 中開始引入ChaCha20 DRNG 配合生成隨機數(shù). Müller 等人[35]從2018 年開始對不同內核版本的LRNG 的實現(xiàn)機制和安全性進行分析, 截止到2020 年4 月已遍歷了Linux 內核版本從4.15 到5.5. 當前, LRNG 的最新架構如圖3 所示, LRNG 維護了兩個不同的熵池(blocking_pool 和input_pool, 而fast_pool 被認為屬于中斷噪聲源) 和一個ChaCha20 DRNG 來收集、壓縮和熵保持, 以及五類熵源.
圖3 中熵池和ChaCha20 DRNG 與熵源之間的相互關系如下:
(1) 輸入熵池(input_pool): 輸入熵池是主要熵池, 它收集并壓縮來自硬件事件的熵, 熵池大小默認為512 字節(jié), 主要目的是將采集的熵提供給阻塞熵池和ChaCha20 DRNG.
圖3 Linux 隨機數(shù)發(fā)生器新的架構Figure 3 New architecture of Linux random number generator
(2) 阻塞熵池(blocking_pool): 也稱輸出熵池, 阻塞熵池從輸入熵池獲取真隨機數(shù)據(jù). 在用戶空間,可以通過/dev/random 設備文件接口或者帶有GRND_RANDOM 標志的getrandom()系統(tǒng)調用訪問, 該熵池大小為1024 字節(jié).
(3) ChaCha20 DRNG: 從輸入熵池獲取種子數(shù)據(jù), 其內部狀態(tài)為 512 比特, 而只有 256 比特(ChaCha20 的關鍵部分) 是由真隨機數(shù)據(jù)填充. 從用戶空間, 可以通過/dev/urandom 或者不帶標志的getrandom() 系統(tǒng)調用訪問; 在內核空間, 可以通過get_random_bytes() 函數(shù)訪問.
(4) 熵源: 共有五種熵源, 各個熵源的特征如下:
(a) 設備驅動程序可以通過add_device_randomness API 提取設備驅動程序開發(fā)者認為包含某些隨機性的數(shù)據(jù), LRNG 采集該類熵源數(shù)據(jù)但并不計算和統(tǒng)計其熵值, 而只是為了用于混淆內部狀態(tài);
(b) Linux 內核為硬件隨機數(shù)發(fā)生器實現(xiàn)了驅動程序, 這些硬件隨機數(shù)發(fā)生器可以通過add_hwgenerator_randomness API 提供真隨機數(shù)據(jù), 該類硬件隨機數(shù)發(fā)生器只有在特定的設備中可用, 即并不是所有的硬件設備都有此類硬件隨機數(shù)發(fā)生器;
(c) 用戶輸入設備(如鍵盤、鼠標等) 可以通過add_input_randomness API 提取熵, 像按鍵或鼠標移動等事件所獲得的數(shù)據(jù)在事件到達時同時使用add_timer_randomness 函數(shù)獲取時間戳作為補充熵源;
(d) 通過add_disk_randomness API 獲取硬件設備事件(如硬盤的讀寫操作) 的隨機性, 與用戶輸入設備熵源相似, LRNG 通過調用add_timer_randomness 函數(shù)為每個磁盤事件添加一個時間戳, 需要注意的是, 并不是所有的設備都有硬盤, 如果使用固態(tài)驅動器(如SSD), 那么此情況下將不提供熵;
(e) 當中斷到達時, LRNG 會被add_interrupt_randominess API 觸發(fā), 對于每個接收到的中斷, LRNG 會獲得一個時間戳和補充數(shù)據(jù), 并將這些數(shù)據(jù)輸入到處理中斷的CPU 所在的快熵池(fast_pool). 為了保持性能, 需要使用fast_pool 而不是直接將數(shù)據(jù)注入到input_pool中. 因為, 接收和處理中斷是性能非常關鍵的代碼路徑, 正常的工作負載每秒會觸發(fā)數(shù)百到數(shù)千個中斷, 而復雜的操作會顯著降低系統(tǒng)性能.
上述列出的熵池(輸入熵池和阻塞熵池) 都可以看作是獨立的隨機數(shù)發(fā)生器. 其中, 輸入熵池與熵源一同構成一個NDRNG; 阻塞熵池可以看作是一個獨立的DRNG, 并通過輸入熵池進行播種; ChaCha20 DRNG 是第三個隨機數(shù)發(fā)生器, 也是通過輸入熵池進行播種. 輸入熵池只會將數(shù)據(jù)輸入到阻塞熵池或者ChaCha20 DRNG,也就是說使用者無法直接從輸入熵池獲取數(shù)據(jù). 從圖2 到圖3 的演變可以看出, LRNG在實現(xiàn)架構上發(fā)生了顯著的變化, 而這種變化的最終目的是為了產生更安全的隨機數(shù).
2013 年, Kim 等人[36]針對操作系統(tǒng)版本為Android ICS 4.0.4 (內核版本為3.0.15) 的內核PRNG和基于此實現(xiàn)的OpenSSL PRNG (簡稱APRNG) 的原理進行了分析, 并以生成SSL 連接過程中的nonce 值為例, 給出APRNG 生成隨機數(shù)的主要過程(見圖4). 根據(jù)圖4 可以看出, 在隨機數(shù)生成的過程中, 每個環(huán)節(jié)的主要熵源數(shù)據(jù)如下:
(1) LRNG: utsname、ktime 和CBN. utsname 包含有關系統(tǒng)和內核的信息, 共六個元素, 包括sysname、nodename、domainname、芯片和內核的版本、編譯內核的時間. 因此, 如果在同一時間段內發(fā)布這些元件, 那么這些元件信息是相同的. ktime 是系統(tǒng)啟動后的納秒級時間; CBN(Comuputed Block Number) 定義為從系統(tǒng)啟動到啟動Zygote 初始化期間, 在/dev/urandom中計算的隨機分組總數(shù)(每個分組10 字節(jié)), 該值取決于設備型號、操作系統(tǒng)版本和通信提供商,通常在100 到250 之間.
(2) Zygote: UID、PID、Time 和Buffer. 其中,UID 為應用程序ID,源碼中是4 字節(jié),但在Android中設置為0; PID 為應用進程ID, 根據(jù)應用程序運行的順序, 按順序分配, PID 在源碼中有15比特的復雜度, 然而Android 的初始化流程和廠商內置的應用是按順序執(zhí)行, 因此Zygote PID小于3000, 并且對于相同型號的設備PID 接近固定值. Time 是指gmt_unix_time(UNIX 時間戳), 單位為秒, 由于應用程序的時間幾乎等于ClientHello 包中的時間, 因此可以對該時間值進行準確的預測. 一旦系統(tǒng)啟動, Zygote 模塊也會啟動, 因此Zygote Time 可以近似等于系統(tǒng)啟動時間. Buffer 是RAM 中存儲的RAND_byte() 輸出的現(xiàn)有值, 它的復雜性取決于在調用RAND_byte() 的函數(shù)中如何對其進行定義和初始化. 用于生成ClientHello nonce 的Buffer 初始化為零, 因此可以將其視為一個常數(shù).
(3) Application APRNG: PID、Time 和Buffer, 其含義與(2) 中相同.
APRNG 在Android 平臺應用廣泛, Android 繼承于Linux, 它的內核PRNG 是基于LRNG 實現(xiàn),從上述三種熵源可以看出主要以LRNG 的/dev/urandom 接口的輸出作為主要熵源, 但對于Android 終端而言, 其缺少像PC 平臺中LRNG 的部分熵源, 如鼠標移動、磁盤操作等. 因此, APRNG 的熵源的隨機性高度依賴系統(tǒng)啟動時從Android 內核PRNG(dev/urandom) 中讀取的數(shù)據(jù).
圖4 Android OpenSSL 隨機數(shù)發(fā)生器Figure 4 Android OpenSSL random number generator
APRNG 的主要接口函數(shù)包括: RAND_poll()、RAND_add() 和 RAND_byte(). 其中, RAND_poll() 使用熵源數(shù)據(jù)初始化隨機數(shù)發(fā)生器的內部狀態(tài), 從操作系統(tǒng)隨機源 (例如,Linux 的/dev/urandom 設備、UID、PID 和 Time 等) 提取熵并將其添加到隨機數(shù)發(fā)生器中;RAND_add(Buf,N,Entropy), 將Buf 數(shù)組中N 字節(jié)數(shù)據(jù)混合到APRNG 中, Entropy 代表Buf 數(shù)據(jù)的熵估計值; RAND_byte(Buf,N), 生成N 字節(jié)的隨機數(shù)并加入到Buf 數(shù)組中.
近年來, 隨著移動智能終端的快速發(fā)展, 移動智能終端逐漸配備越來越多的傳感器(如加速度計、磁力計、陀螺儀、環(huán)境溫度/濕度傳感器等), 這些傳感器可以采集移動設備周邊環(huán)境和設備用戶行為等信息,而這些數(shù)據(jù)具有一定的不確定性. 由于該方法不需要額外的硬件支持, 與移動智能終端具有高度融合, 因此國外的一些研究工作開始關注于從移動智能終端(如Android 移動智能終端) 傳感器所采集的數(shù)據(jù)中提取隨機性來生成隨機數(shù)[37-39].
Windows 操作系統(tǒng)密碼庫提供了一些Windows 應用程序開發(fā)人員可以使用的功能, 像加解密、密鑰存儲、雜湊函數(shù)、簽名、隨機數(shù)生成等. Crypto API (CAPI) 及其隨機數(shù)生成機制是在Windows XP和更早版本的Windows 系統(tǒng)中引入的(Windows 95 中首次引入). Crypto API 中的隨機數(shù)生成函數(shù)CryptGenRandom 使用了四個SHA-1 函數(shù), 這些函數(shù)通過系統(tǒng)熵進行播種[15]. 內部生成器函數(shù)使用RC4 密碼算法向用戶端發(fā)送生成的隨機數(shù), 并使用MD4 密碼雜湊算法接收用戶提供的附加熵. 由于在Windows XP 和Windows 2000 的WRNG 中發(fā)現(xiàn)嚴重漏洞, 促使微軟在Windows Vista、Windows 8等新版本的系統(tǒng)中引入了一個新的密碼庫CNG (Cryptography API: Next Generation)[40]. Gutterman等人[15]的研究給出了CNG 的整體架構(見圖5), 主要由BCrypt 和NCrypt 組成, 其中BCrypt 提供密碼原語(如隨機數(shù)發(fā)生器、雜湊函數(shù)、簽名、加解密等), 支持用戶模式和內核模式; NCrypt 提供密鑰存儲功能, 僅支持用戶模式. 基于BCrypt 的新的隨機數(shù)生成函數(shù)BCryptGenRandom 為基于CTR 模式的分組密碼算法實現(xiàn)的DRNG.
圖5 CNG 的整體結構Figure 5 Whole structure of CNG
CNG 函數(shù)和接口位于內核和用戶模式, CNG.SYS 是位于內核模式的一個密碼模塊, 為Windows內核組件和內核模式的應用提供密碼服務. 2015 年, 在Alzhrani 等人[16]的研究工作中給出了有關Windows 8 中CNG 隨機數(shù)生成機制較為詳細的介紹. 在Windows 8 中,內核模式的密碼庫CNG.SYS(如圖6 所示) 可以通過四個邏輯接口訪問, 包括CNG BCrypt、Legacy API、SystemPrng Interface 和Entropy API. Entropy API 邏輯接口用于采集由熵源產生的真隨機數(shù)據(jù), 為CNG.SYS 中的DRNG 提供熵. CNG.SYS 產生的隨機數(shù)用作用戶或內核PRNG 的種子, 并通過SystemPrng 邏輯接口提供. 相比于CryptGenRandom 函數(shù), BCryptGenRandom 除了采集系統(tǒng)數(shù)據(jù)作為熵源外, 也支持采集寄存器數(shù)據(jù)、可信平臺模塊(TPM) 生成的數(shù)據(jù)(如果TPM 可用)、系統(tǒng)時間、RDRAND CPU 指令輸出的隨機數(shù)(如果CPU 支持) 等作為熵源.
圖6 CNG 邊界Figure 6 CNG boundaries
文獻[16] 中給出Windows 8 系統(tǒng)在啟動階段和運行階段的熵生成方法: (1) 系統(tǒng)啟動階段: 啟動時, 通過Windows 操作系統(tǒng)加載程序獲得一個初始熵值, 采集的熵源包括: 寄存器值、TPM 生成的隨機數(shù)(如果TPM 可用)、當前系統(tǒng)時間、OEM0 ACPI 表內容、RDRAND CPU 指令的輸出(如果設備支持)、UEFI 隨機數(shù)發(fā)生器輸出(如果從UEFI 固件啟動)、CPU 計時和管理員提供的注冊表值的可選內容. 然后, 通過SHA-512 對采集的原始熵源數(shù)據(jù)進行處理. (2) 啟動后運行階段: 除啟動階段的熵源數(shù)據(jù)外, Windows 熵池同時填充其他三個額外熵源數(shù)據(jù): 高精度CPU 時鐘計數(shù)器值、TPM 輸出、RARAND CPU 指令, 這三類熵源數(shù)據(jù)被輸入到熵池但不使用雜湊函數(shù). 由于Windows 系統(tǒng)的源碼不公開, 因此關于Windows RNG 的相關研究較少. 2019 年10 月, 微軟發(fā)布了一項有關Windows 10 RNG 簡要介紹的白皮書[41], 據(jù)該白皮書介紹, Windows 10 RNG 的重播種機制如下: 在系統(tǒng)啟動時, 第一次初始化種子是在系統(tǒng)啟動后1 秒執(zhí)行, 后面每次重播種的時間間隔是原來的三倍, 即在后續(xù)的第3 秒、第9 秒、第27 秒等都會進行重播種操作, 時間間隔不斷增加直到達到閾值, 目前該閾值是3600 秒(1 小時). 此外, 與Linux RNG 一樣, Windows RNG 的輸出函數(shù)也是基于CTR 模式的AES 分組密碼算法實現(xiàn)的DRNG(遵循NIST SP800-90A 標準).
Yarrow 隨機數(shù)發(fā)生器由Kelsey 等人[7]提出, 應用于iOS、Mac 和FreeBSD 等操作系統(tǒng)上. 由于Yarrow 隨機數(shù)發(fā)生器輸出序列的質量在很大程度上依賴于熵估計方法的準確性, 為此Viega 等人[17]在Yarrow 的基礎上, 選擇去掉了熵估計環(huán)節(jié), 通過多熵池來保證至少有一個熵池積累足夠的熵來提供安全性, 提出了Fortuna 隨機數(shù)發(fā)生器. 下面介紹Yarrow 和Fortuna 隨機數(shù)發(fā)生器的基本結構和設計思想.
3.4.1 Yarrow 隨機數(shù)發(fā)生器
Yarrow 隨機數(shù)發(fā)生器的基本框架如圖7 所示, 其產生隨機數(shù)主要包括以下三個環(huán)節(jié): (1) 熵采集器采集熵源數(shù)據(jù)并添加入熵池(包含快熵池和慢熵池) 中, 熵池統(tǒng)計同種熵源事件類型的熵值; (2) 重播種控制器檢查熵池數(shù)據(jù)熵值是否達到閾值, 若達到, 則執(zhí)行重播種操作產生新的密鑰; (3) 輸出單元產生請求所需長度的隨機數(shù).
圖7 Yarrow 隨機數(shù)發(fā)生器的基本框架Figure 7 General framework of Yarrow random number generator
下面對Yarrow 隨機數(shù)發(fā)生器的各個組件功能進行介紹.
熵采集: Yarrow RNG 的熵源包括鍵盤/鼠標操作、網絡數(shù)據(jù)包到達時間等隨機事件. 熵采集器先從熵源收集數(shù)據(jù)并對熵源數(shù)據(jù)進行雜湊運算, 再將處理后的數(shù)據(jù)交替放入Yarrow RNG 的兩個熵池中(快熵池和慢熵池). 其中, 快熵池提供密鑰的頻繁重播種, 當熵估計較準確時, 快熵池可以確保密鑰泄露時間盡可能的短; 慢熵池提供一種相對保守的密鑰重播種方案, 即便出現(xiàn)高估熵的情形, 慢熵池仍可以做到其聲稱安全的重播種.
熵估計: Yarrow 隨機數(shù)發(fā)生器沒有直接指定具體的熵估計方法, 只提供了熵測量的總體方案. 對熵源數(shù)據(jù)分別應用三種熵測量方法: (1) 第一種方法是系統(tǒng)內置熵源事件的熵估計值, 如定義鼠標移動事件的熵值是4 比特; (2) 第二種方法是用專門的熵估計器來估計熵值; (3) 第三種方法是將熵源數(shù)據(jù)長度乘以一個小于1 的常數(shù)因子(文獻[7] 中建議為0.5) 的值作為熵估計值. 最后, 比較這三種測量方法得到的熵值,將最小值作為熵估計的最終值.
重播種: 用于更新熵池, 以免密鑰泄露使隨機數(shù)發(fā)生器的內部狀態(tài)受到安全威脅. 對Yarrow 發(fā)生器而言, 如果快熵池中任何一種熵源的熵累加值達到閾值, 則進行重播種操作, 即使用當前密鑰和快熵池數(shù)據(jù)來產生新的密鑰; 如果慢熵池有任意k類熵源的熵累加值達到閾值, 則進行重播種操作, 此時使用當前密鑰、快熵池數(shù)據(jù)和慢熵池數(shù)據(jù)來產生新的密鑰. 以Yarrow-160 為例, 快熵池閾值是100 比特, 慢熵池重播種操作要求至少兩種熵源的熵累加值都達到160 比特. 重播種操作結束后, 需要將對應熵池中熵估計值重置為0. Yarrow-160 使用SHA-1 算法對滿足重播種條件的熵池數(shù)據(jù)進行運算.
輸出單元: Yarrow 發(fā)生器輸出單元是基于CTR 模式的3DES 密碼算法實現(xiàn), 并設置了輸出門限, 即記錄已輸出的隨機數(shù)組數(shù). 當輸出單元的輸出組數(shù)達到輸出門限時, 將隨機數(shù)發(fā)生器下一步輸出的K比特作為新密鑰. 以Yarrow-160 為例, 輸出單元的輸出門限為10.
3.4.2 Fortuna 隨機數(shù)發(fā)生器
Fortuna 隨機數(shù)發(fā)生器生成隨機數(shù)包含三個主要過程: (1) 計算機重啟時, 讀取種子文件內容作為發(fā)生器初始的內部狀態(tài), 確保啟動時發(fā)生器能夠正常生成隨機數(shù); (2) 熵采集器采集熵源事件數(shù)據(jù)并將其添加到熵池中; (3) 輸出單元生成隨機數(shù), 輸出單元會檢查是否滿足重播種條件, 若滿足, 則執(zhí)行重播種操作并更新密鑰; 若不滿足, 則不更新密鑰; (4) 最后將密鑰和計數(shù)器值作為CTR 模式分組密碼算法的輸入來生成隨機數(shù). Fortuna 發(fā)生器為每種熵源設定編號(范圍從0 到255), 該發(fā)生器包含32 個熵池, 熵池編號依次從0 到31, 記作P0,P1,··· ,P31. 下面對Fortuna 發(fā)生器的關鍵功能組件的工作原理進行介紹.
啟動階段: 每次重啟計算機時, 直接讀種子文件來初始化發(fā)生器內部狀態(tài). 從安全角度考慮, 種子文件需要更新. 最簡單的辦法是當計算機關機時, 將發(fā)生器內部狀態(tài)寫入種子文件. 但由于機器可能出現(xiàn)異常關閉情形, 所以發(fā)生器需要在固定時間間隔內重寫種子文件, 例如, 每隔十分鐘重寫種子文件. 當?shù)谝淮螁影l(fā)生器時, 沒有種子文件用于重播種操作, 例如, 剛出廠的計算機需要發(fā)生器生成初始管理密鑰, 但同一工廠批量生產的同一型號計算機的配置相同, 并且裝載了相同的數(shù)據(jù). 為了增加安全性, 這些裝載數(shù)據(jù)不能當作隨機數(shù)發(fā)生器的初始狀態(tài), 只能累積足夠的熵源數(shù)據(jù)來觸發(fā)重播種操作, 這可能需要很長時間. 在這種情況下, Viega 等人建議用外部隨機源來創(chuàng)建初始種子文件, 如軟件安裝期間讓測試人員移動鼠標來收集初始熵源數(shù)據(jù).
熵采集: Fortuna 發(fā)生器最多允許256 種熵源事件, 如用戶鼠標/鍵盤操作、麥克風采集的噪聲等, 將收集來的熵源數(shù)據(jù)添加到32 個熵池中. 最簡單的方案是由熵采集器決定熵源數(shù)據(jù)加入哪個熵池, 但這種方案存在安全隱患, 因為需要調用某些函數(shù)把事件傳遞給采集器, 攻擊者可能也會對這些函數(shù)做額外調用.為保證每種熵源數(shù)據(jù)在熵池中分布更均勻, Fortuna 熵采集器將采集到的每種熵源數(shù)據(jù)循環(huán)添加到32 個熵池中.
重播種操作: 相比于Yarrow 發(fā)生器, Fortuna 采取了新的重播種策略來更新內部狀態(tài). 進行重播種的條件是第一個熵池P0中數(shù)據(jù)長度大于設定的最小熵池空間(一般是64 字節(jié)), 并且距離上一次重播種時間超過100 毫秒, 當這兩個條件同時滿足時, 則執(zhí)行重播種操作. 具體重播種規(guī)則如下: 將重播種操作編號記作r, 熵池編號記作i. 當2i整除r, 則熵池i包含在第r次重播種操作中. 由此可知,P0每次都參與重播種,P1每隔一次參與重播種,P2每隔四次參與重播種. 每一次完成重播種操作后, 清空參與重播種熵池的數(shù)據(jù).
輸出單元: 輸出單元通過基于CTR 模式的分組密碼算法計算后生成隨機數(shù), 內部狀態(tài)包含256 比特的分組密鑰和128 比特的計數(shù)器. 當外部請求生成隨機數(shù)時, 輸出單元調用密碼算法生成偽隨機數(shù). 在每個請求完成后, 輸出單元會額外產生一個256 比特的隨機數(shù), 將其作為CTR 模式的分組密碼算法的新密鑰.
下面從熵源、熵池、熵估計、重播種機制、隨機數(shù)輸出單元等方面,給出了Linux、Android、Windows、iOS 等幾種典型操作系統(tǒng)平臺的軟件隨機數(shù)發(fā)生器設計的比較(見表1). 綜合來看, LRNG 是這幾種典型操作系統(tǒng)平臺中應用最為廣泛的軟件隨機數(shù)發(fā)生器, 因為Android 平臺的APRNG 也是基于LRNG 實現(xiàn)的. 此外, 由于Linux 是開源項目, 因此對LRNG 開展的相關研究也較多. 實際上, 各種典型操作系統(tǒng)平臺的軟件隨機數(shù)發(fā)生器設計都基本遵循圖1 給出的基本結構, 只是在軟件RNG 的具體設計和實現(xiàn)上有一定的差異. 在熵源的選取上, 軟件隨機數(shù)發(fā)生器的熵源基本上都是源于操作系統(tǒng)數(shù)據(jù)或平臺外設輸入的隨機性, 或者平臺所支持的一些硬件隨機數(shù)發(fā)生器的輸出; 在熵估計方法上, 由于系統(tǒng)數(shù)據(jù)或平臺外設輸入屬于非物理熵源, 各典型平臺的軟件RNG 都有自己的熵估計方案; 為了保證后向安全性, 各平臺軟件RNG 設計方案中采用了不同的(重) 播種機制.
表1 不同平臺軟件隨機數(shù)發(fā)生器的比較Table 1 Comparison of software random number generators in different platforms
由于軟件RNG 在Linux、Android、Windows 等操作系統(tǒng)平臺具有廣泛應用, 其安全性也日益受到人們的關注. 根據(jù)以往的研究工作, 軟件RNG 安全性研究的關注點主要集中在以下幾個方面:
· 有效熵源的選取;
· 面向熵源的熵估計技術準確度;
· 其他安全關注點, 如前向/后向安全性、拒絕服務攻擊、運行環(huán)境的安全性.
針對這些設計或使用上的安全關注點, 在過去的一二十年內人們研究發(fā)現(xiàn)軟件RNG 產生的隨機數(shù)存在被預測的可能性, 進而導致用到這些隨機數(shù)服務的密碼應用系統(tǒng)存在被破解的風險. 進一步地,APRNG 實現(xiàn)源碼和算法并不公開, 只對外提供了調用接口, 且APRNG 的熵源數(shù)據(jù)主要來源于LRNG dev/urandom 接口產生的數(shù)據(jù). WRNG 目前已將BCryptGenRandom 取代CryptGenRandom, 但沒有對BCryptGenRandom 設計和實現(xiàn)算法進行分析的相關研究內容. Yarrow 發(fā)生器應用于早期Mac 操作系統(tǒng)平臺中, Fortuna 是對Yarrow 的改進, 去掉了熵估計模塊. 鑒于LRNG 是目前使用最為廣泛的軟件形態(tài)隨機數(shù)發(fā)生器之一, 而且Linux 操作系統(tǒng)的開源性, 使得LRNG 的設計原理和安全性一直備受研究人員的關注. 本節(jié)將結合LRNG, 圍繞以上三個方面的安全性分析關注點進行闡述.
軟件RNG 熵源的選取通?;谲浖脚_上已有的硬件(如CPU、磁盤) 或外設(如鍵盤、鼠標), 以及可以采集平臺所處運行環(huán)境參數(shù)的器件(如傳感器) 等, 而并非專門設計的硬件電路(如振蕩器). 雖然一些通用操作系統(tǒng)平臺在經歷多次迭代更新后,可以支持硬件RNG 的輸出(如RDRAND 指令)或TPM輸出等作為補充熵源, 彌補操作系統(tǒng)中隨機數(shù)服務熵不足的問題. 但是, 不同的計算機體系架構導致了熵源種類的不同, 即便體系架構相似, 不同場景下的熵源活躍程度也不盡相同. 因此, 在不同平臺、不同場景下調用軟件RNG 服務時, 熵源的熵供給能力差異很大, 這也導致軟件RNG 存在從熵源獲取到的隨機性質量存在差異甚至無法得到保證的問題.
例如, 個人電腦或者移動智能終端平臺通常接有鍵盤、鼠標等外設, 且有豐富的傳感器, 則熵供給能力較強; 而路由器等網路設備的主要熵源是網絡中斷, 不具備其他隨機性來源, 則熵供給能力一般, 正如Gutterman 等人[13]所分析的, 像OpenWRT 無線路由器所含有的熵源是非常有限的(缺乏硬件外設鍵盤、鼠標等的支持), 這類設備上唯一的LRNG 熵源是網絡中斷, 而敵手是容易對網絡中斷進行觀測的. 此外, 目前廣泛使用的固態(tài)硬盤無法和傳統(tǒng)磁盤一樣提供足夠的熵源.
那么, 如何結合操作系統(tǒng)平臺自身特點, 選取合適的熵源為軟件RNG 提供充足的隨機性, 是軟件RNG 能否對外提供高質量隨機數(shù)服務的關鍵. 而盡可能多發(fā)掘并使用不同種類的熵源, 可從一定程度上緩解熵源隨機性不足的問題, 像LRNG 和Windows RNG 在版本更新中都努力嘗試引入更豐富的熵源.
軟件RNG 一般基于密碼算法設計對種子進行擴展來產生隨機數(shù), 種子的不確定性由外界輸入的熵源數(shù)據(jù)決定. 美國NIST SP800-90A 標準推薦了生成隨機數(shù)的擴展算法, 包括基于密碼雜湊算法、基于對稱密碼算法等結構. 保證軟件RNG 達到所聲稱的安全強度的前提, 是要確保輸入的熵需要滿足一定要求,而對于熵的量化估計研究則成為重點. 相比而言, 在傳統(tǒng)硬件平臺上的熵源結構一般較為清晰, 隨機行為(stochastic behavior) 比較穩(wěn)定, 選用合適的現(xiàn)有熵估計模型理論或統(tǒng)計熵估計方法就可以對熵進行較為準確的估計, 從而保證所設計的發(fā)生器輸入的熵滿足要求. 但是, 對于軟件平臺, 軟件RNG 的隨機性來源大多是行為難以確定的非物理事件, 如鍵盤鼠標的操作、磁盤讀寫狀態(tài), 而使用一個模型或統(tǒng)計方法對這些事件的熵進行刻畫或估量是困難的. 而且, 這些熵源的隨機行為并非是穩(wěn)態(tài)的, 包含的熵值會隨著時間而變化, 也有可能在一段時間內受到物理環(huán)境或人為因素影響導致熵值變低, 這就會使得隨機數(shù)發(fā)生器內部的狀態(tài)可破解, 進一步預測出輸出的隨機數(shù).
目前現(xiàn)有的熵估計方法都無法針對軟件RNG 中基于非物理事件的熵源進行有效的熵估計, ISO/IEC 18031 和德國AIS 20/31 標準中使用的理論建模的方法也需要熵源是物理的、平穩(wěn)的; SP800-90B 統(tǒng)計熵估計方法也需要熵源是穩(wěn)態(tài)的, 但并沒有給出機制來判斷穩(wěn)態(tài)或非穩(wěn)態(tài). 雖然在LRNG 中給出了一個簡潔的熵估計方法, 但被指出存在明顯低估問題[35]. 在早期的Mac 系統(tǒng)中的軟件RNG (即Yarrow 發(fā)生器結構) 也曾經有過熵估計部件, 但也因為準確性原因在后續(xù)版本中移除了. 因此, 如何對軟件RNG 的熵源進行準確熵估計, 目前仍是一個亟待解決的問題.
除了上述軟件RNG 的安全性分析關注點外, 安全性方面的其他關注點還包括前向/后向安全性、拒絕服務攻擊、運行環(huán)境的安全性等.
前向/后向安全性. 在早期的LRNG 版本中, 若攻擊者獲取到了LRNG 在某個時刻的內部狀態(tài), 則恢復該狀態(tài)出現(xiàn)之前的LRNG 輸出是存在可能的. 在文獻[13] 所針對的Linux 內核版本上, 當時的LRNG被分析出無法完全滿足前向安全性的要求, Gutterman 等人利用內部狀態(tài)更新函數(shù)啟動機制的缺陷, 以及更新函數(shù)不具備單向性問題, 他們在已知當前發(fā)生器內部狀態(tài)前提下計算出上一時刻的內部狀態(tài), 并完成了對之前時刻輸出的恢復. 隨后, Gutterman 等人對LRNG 內部工作機制給出優(yōu)化建議以保證其前向安全性. 文獻[19] 的研究工作中, Lacharme 等人對LRNG 的設計加以改進, 從而使LRNG 設計可以阻止Gutterman 等人提出的攻擊.
拒絕服務攻擊. 文獻[13] 中提出了兩種不同的拒絕服務攻擊. 第一種是通過/dev/random 直接讀取相應數(shù)據(jù). 由于當時的LRNG 版本對調用隨機數(shù)服務的用戶沒有任何限制, 也沒有制定優(yōu)先級策略, 從而導致其他用戶可能在很長一段時間無法獲取到隨機數(shù)據(jù). 另一種是持續(xù)不斷地通過/dev/urandom 讀取非阻塞熵池中的數(shù)據(jù), 使得LRNG 輸入熵池中的熵來不及補充, 進而間接地造成阻塞熵池中的熵難以累計, 致使/dev/random 面臨拒絕服務的問題. 在Linux 內核4.8 版本上, 設計者們開始使用ChaCha20 DRNG 來取代非阻塞熵池, 從而消除了這個問題. ChaCha20 DRNG 每5 分鐘完成一次重播種, 這一機制使得內部的熵供給和后向安全性得到改善. 此外, 如Lacharme 等人所述, 在后期內核版本的LRNG 輸入熵池中專門為/dev/random 留存了一部分含熵數(shù)據(jù), 并且外界是無法通過對ChaCha20 DRNG 的操作來獲取這部分留存數(shù)據(jù)的, 從而降低了/dev/random 受到拒絕服務攻擊的風險.
運行環(huán)境的安全性. 軟件RNG 的安全性與其所處運行環(huán)境的安全性有著直接的關系. 在BSI 團隊的研究報告[35]中指出, LRNG 的安全需要依賴于安全的Linux 內核和內核運行環(huán)境, 如果一個攻擊者可以觀察到LRNG 的內部狀態(tài)或者熵源的行為, 那么LRNG 的熵將不存在. 只有通過主機執(zhí)行平臺對LRNG 提供一個安全域, 才能實現(xiàn)對LRNG 的內部狀態(tài)等環(huán)節(jié)的保護, 例如, 保證執(zhí)行環(huán)境的物理安全、通過適當?shù)难a丁管理機制確保Linux 內核及時進行安全更新、為LRNG 使用可信的執(zhí)行環(huán)境(如使用可信硬件) 等.
隨機數(shù)發(fā)生器所產生的隨機數(shù)為密碼算法、密碼協(xié)議、數(shù)字簽名等密碼技術提供基礎的安全保障. 隨著智能移動終端、物聯(lián)網設備等便攜式設備的不斷普及和移動互聯(lián)網、物聯(lián)網等技術的快速發(fā)展, 以及軟件密碼模塊在我國逐步興起和廣泛應用, 傳統(tǒng)的硬件RNG 已不能完全滿足當前密碼應用對隨機數(shù)服務的需求, 軟件RNG 的設計成為未來重要的發(fā)展趨勢. 本文主要總結了目前較為典型的操作系統(tǒng)平臺上所使用的軟件形式隨機數(shù)發(fā)生器的基本結構和隨機數(shù)產生原理, 并從熵源的隨機性質量、熵源的熵估計技術準確度、前向/后向安全性等方面對這些發(fā)生器的安全性進行分析. 該工作全面地梳理了典型操作系統(tǒng)上的隨機數(shù)發(fā)生器設計與實現(xiàn), 以及安全性問題分析, 對我國未來軟件形式的隨機數(shù)發(fā)生器的設計與檢測、標準規(guī)范的研制等工作具有重要的參考意義.