<p><b>/dev/random</b>在類UNIX系統中是一個特殊的裝置檔案，可以用作亂數發生器或偽亂數發生器。
</p>


<h2><span id=".E5.AE.9E.E7.8E.B0"></span><span id="实现">實現</span></h2>
<p>並不是所有作業系統中的<b>/dev/random</b>的實現都是相同的。以下列舉了一些作業系統中的實現。
</p>
<h3><span id="Linux">Linux</span></h3>
<p>Linux核心中的是第一個以背景噪聲產生真正的亂數產生的實現，它允許程式存取來自裝置驅動程式或其它來源的背景噪聲。
</p><p>1994年，美國程式設計師曹子德（Theodore Y. Ts'o）第一次在Linux核心中實現了亂數發生器。使用了SHA-1雜湊演算法而非密碼，以避開法律限制。另一個原因是任意給定的雜湊或密碼加密強度弱，而新亂數發生器在提高了密碼強度。
</p><p>發生器有一個容納噪聲資料的熵池，在讀取時，<code>/dev/random</code>裝置會返回小於熵池噪聲總數的隨機位元組。<code>/dev/random</code>可生成高隨機性的公鑰或一次性密碼本。若熵池空了，對<code>/dev/random</code>的讀操作將會被阻塞，直到收集到了足夠的環境噪聲為止。這樣的設計使得<code>/dev/random</code>是真正的亂數發生器，提供了最大可能的亂數據熵，建議在需要生成高強度的金鑰時使用。
</p><p><code>/dev/random</code>的一個副本是<code>/dev/urandom</code>（「unblocked」，非阻塞的亂數發生器），它會重複使用熵池中的資料以產生偽亂數據。這表示對<code>/dev/urandom</code>的讀取操作不會產生阻塞，但其輸出的熵可能小於<code>/dev/random</code>的。它可以作為生成較低強度密碼的偽亂數生成器，不建議用於生成高強度長期密碼。
</p><p><code>/dev/random</code>也允許寫入，任何使用者都可以向熵池中加入亂數據。即使寫入非亂數據亦是無害的，因為只有管理員可以呼叫ioctl以增加熵池大小。Linux核心中當前熵的值和大小可以通過存取<code>/proc/sys/kernel/random/</code>資料夾中的檔案得到。
</p><p>2006年3月，Gutterman、Pinkas和Reinman發表了對Linux亂數發生器的詳細密碼學分析，其中提出了該發生器的幾個弱點。也許其中最嚴重的問題發生在嵌入式系統和Live CD系統，類似路由器和無盤工作站中的應用。在這些系統中，引導狀態是可預測的，且環境熵的來源也較為受限。對於有NVRAM的系統，他們建議在關機時儲存一部分亂數發生器的狀態，使得在下次開機時可以恢復這些狀態。對於路由器而言，網路資料是熵的主要來源，他們認為在重新啟動前後儲存和恢復資料可能要求潛在的攻擊者要麼竊聽從路由器投入使用開始全部的網路資訊，或直接取得路由器的內部狀態。他們寫道，這個問題對於無線路由器而言尤其關鍵，因為其網路資訊可以遠端取得到，並可能用於產生資料加密用金鑰的隨機發生器。
</p>
<h3><span id="FreeBSD">FreeBSD</span></h3>
<p>FreeBSD作業系統實現了256位的Yarrow演算法變體，以提供偽亂數流。與Linux的<code>/dev/random</code>不同，FreeBSD的<code>/dev/random</code>不會產生阻塞，與Linux的<code>/dev/urandom</code>相似，提供了密碼學安全的偽亂數發生器，而不是基於熵池。而FreeBSD的<code>/dev/urandom</code>則只是簡單的連結到了<code>/dev/random</code>。
</p><p>Yarrow演算法的前提是現代的偽亂數發生器的安全性很高，若其內部狀態不為攻擊者所知，且比熵估計更易理解。在某些情況下，攻擊者可以在某種程度上掌握熵的量，例如無盤伺服器的熵幾乎全部來自於網路，使得它可能易受中間人攻擊的影響。演算法的種子會被規則的重設：在網路和磁碟負載較輕的系統上，一秒內種子可能被重設數次。
</p><p>FreeBSD也支援硬體亂數發生器，並在安裝了類似硬體時會替代Yarrow演算法。
</p><p>2004年，Landon Curt Noll測試了FreeBSD 5.2.1版本的<code>/dev/random</code>，發現它不是一個密碼學強的亂數發生器，因為其輸出在十億位測試中顯示出了多個一致性缺陷。類似的缺陷亦發生在Linux 2.4.21-20，Solaris 8 patch 108528-18和Mac OS X 10.3.5的<code>/dev/random</code>中。
</p>
<h3><span id=".E5.85.B6.E5.AE.83.E6.93.8D.E4.BD.9C.E7.B3.BB.E7.BB.9F"></span><span id="其它操作系统">其它作業系統</span></h3>
<p><code>/dev/random</code>和<code>/dev/urandom</code>也存在於
Solaris、Mac OS X、NetBSD、OpenBSD、Tru 64 UNIX 5.1B、AIX 5.2和HP-UX 11i v2中。與FreeBSD的實現類似，AIX採用了它自身的基於Yarrow的設計，但AIX使用的熵源數量低於標準<code>/dev/random</code>的實現，並且在系統認為熵池的熵達到足夠值時停止填充熵池。
</p><p>在Windows NT中，<code>ksecdd.sys</code>提供了類似的功能，但讀取特殊檔案<code>\Device\KsecDD</code>並不會提供與UNIX中相同的功能。開發文件中提到的，用於產生密碼用亂數據的函式是CryptGenRandom和RtlGenRandom。
</p><p>雖然DOS沒有原生的提供類似功能，但有開源的Noise.sys（頁面存檔備份，存於網際網路檔案館）提供了類似功能。該實現與<code>/dev/random</code>的功能和介面類似，即建立了兩個裝置，RANDOM$與URANDOM$，也可以通過/DEV/RANDOM$和/DEV/URANDOM$存取。
</p>
<h2><span id="EGD">EGD</span></h2>
<p>EGD（熵收集守護行程，Entropy Gathering Daemon）通常可以在不支援<code>/dev/random</code>裝置的UNIX系統中提供類似的功能。這是一個執行於使用者態的守護行程，提供了高品質的密碼用亂數據。一些加密軟體，例如OpenSSL，GNU Privacy Guard和Apache HTTP伺服器支援在<code>/dev/random</code>不可用的時候使用EGD。
</p><p>EGD（頁面存檔備份，存於網際網路檔案館），或者類似的軟體，例如prngd（頁面存檔備份，存於網際網路檔案館），可以從多種來源收集偽隨機的熵，並對這些資料進行處理以去除偏置，並改善密碼學品質，然後允許其它程式通過UNIX域套介面（通常使用<b><code>/dev/egd-pool</code></b>），或TCP套介面存取其輸出。該程式通常使用建立子行程的以查詢系統狀態的方式來收集熵。它查詢的狀態通常是易變的、不可預測的，例如CPU、I/O、網路的使用率，也可能是一些紀錄檔檔案和臨時目錄中的內容。
</p>
<h2><span id=".E5.8F.82.E8.80.83.E6.96.87.E7.8C.AE"></span><span id="参考文献">參考文獻</span></h2>

<ul><li>Biege, Thomas; Analysis of a strong Random Number Generator Slides</li></ul><h2><span id=".E5.8F.82.E8.A7.81"></span><span id="参见">參見</span></h2>
<ul><li>Unix哲學</li>
<li>標準流</li>
<li>/dev/full</li>
<li>/dev/null</li>
<li>/dev/zero</li>
<li>/dev</li>
<li>硬體亂數生成器</li>
<li>密碼學安全偽亂數生成器</li>
<li>Yarrow演算法</li>
<li>Fortuna演算法</li></ul>
**/dev/random** 在類 UNIX 系統中是一個特殊的裝置檔案，可以用作亂數發生器或偽亂數發生器。

## 實現

並不是所有作業系統中的 **/dev/random** 的實現都是相同的。以下列舉了一些作業系統中的實現。

### Linux

Linux 核心中的是第一個以背景噪聲產生真正的亂數產生的實現，它允許程式存取來自裝置驅動程式或其它來源的背景噪聲。

1994 年，美國程式設計師曹子德（Theodore Y. Ts'o）第一次在 Linux 核心中實現了亂數發生器。使用了 SHA-1 雜湊演算法而非密碼，以避開法律限制。另一個原因是任意給定的雜湊或密碼加密強度弱，而新亂數發生器在提高了密碼強度。

發生器有一個容納噪聲資料的熵池，在讀取時，`/dev/random` 裝置會返回小於熵池噪聲總數的隨機位元組。`/dev/random` 可生成高隨機性的公鑰或一次性密碼本。若熵池空了，對 `/dev/random` 的讀操作將會被阻塞，直到收集到了足夠的環境噪聲為止。這樣的設計使得 `/dev/random` 是真正的亂數發生器，提供了最大可能的亂數據熵，建議在需要生成高強度的金鑰時使用。

`/dev/random` 的一個副本是 `/dev/urandom`（「unblocked」，非阻塞的亂數發生器），它會重複使用熵池中的資料以產生偽亂數據。這表示對 `/dev/urandom` 的讀取操作不會產生阻塞，但其輸出的熵可能小於 `/dev/random` 的。它可以作為生成較低強度密碼的偽亂數生成器，不建議用於生成高強度長期密碼。

`/dev/random` 也允許寫入，任何使用者都可以向熵池中加入亂數據。即使寫入非亂數據亦是無害的，因為只有管理員可以呼叫 ioctl 以增加熵池大小。Linux 核心中當前熵的值和大小可以通過存取 `/proc/sys/kernel/random/` 資料夾中的檔案得到。

2006 年 3 月，Gutterman、Pinkas 和 Reinman 發表了對 Linux 亂數發生器的詳細密碼學分析，其中提出了該發生器的幾個弱點。也許其中最嚴重的問題發生在嵌入式系統和 Live CD 系統，類似路由器和無盤工作站中的應用。在這些系統中，引導狀態是可預測的，且環境熵的來源也較為受限。對於有 NVRAM 的系統，他們建議在關機時儲存一部分亂數發生器的狀態，使得在下次開機時可以恢復這些狀態。對於路由器而言，網路資料是熵的主要來源，他們認為在重新啟動前後儲存和恢復資料可能要求潛在的攻擊者要麼竊聽從路由器投入使用開始全部的網路資訊，或直接取得路由器的內部狀態。他們寫道，這個問題對於無線路由器而言尤其關鍵，因為其網路資訊可以遠端取得到，並可能用於產生資料加密用金鑰的隨機發生器。

### FreeBSD

FreeBSD 作業系統實現了 256 位的 Yarrow 演算法變體，以提供偽亂數流。與 Linux 的 `/dev/random` 不同，FreeBSD 的 `/dev/random` 不會產生阻塞，與 Linux 的 `/dev/urandom` 相似，提供了密碼學安全的偽亂數發生器，而不是基於熵池。而 FreeBSD 的 `/dev/urandom` 則只是簡單的連結到了 `/dev/random`。

Yarrow 演算法的前提是現代的偽亂數發生器的安全性很高，若其內部狀態不為攻擊者所知，且比熵估計更易理解。在某些情況下，攻擊者可以在某種程度上掌握熵的量，例如無盤伺服器的熵幾乎全部來自於網路，使得它可能易受中間人攻擊的影響。演算法的種子會被規則的重設：在網路和磁碟負載較輕的系統上，一秒內種子可能被重設數次。

FreeBSD 也支援硬體亂數發生器，並在安裝了類似硬體時會替代 Yarrow 演算法。

2004 年，Landon Curt Noll 測試了 FreeBSD 5.2.1 版本的 `/dev/random`，發現它不是一個密碼學強的亂數發生器，因為其輸出在十億位測試中顯示出了多個一致性缺陷。類似的缺陷亦發生在 Linux 2.4.21-20，Solaris 8 patch 108528-18 和 Mac OS X 10.3.5 的 `/dev/random` 中。

### 其它作業系統

`/dev/random` 和 `/dev/urandom` 也存在於
Solaris、Mac OS X、NetBSD、OpenBSD、Tru 64 UNIX 5.1B、AIX 5.2 和 HP-UX 11i v2 中。與 FreeBSD 的實現類似，AIX 採用了它自身的基於 Yarrow 的設計，但 AIX 使用的熵源數量低於標準 `/dev/random` 的實現，並且在系統認為熵池的熵達到足夠值時停止填充熵池。

在 Windows NT 中，`ksecdd.sys` 提供了類似的功能，但讀取特殊檔案 `\Device\KsecDD` 並不會提供與 UNIX 中相同的功能。開發文件中提到的，用於產生密碼用亂數據的函式是 CryptGenRandom 和 RtlGenRandom。

雖然 DOS 沒有原生的提供類似功能，但有開源的 Noise.sys（頁面存檔備份，存於網際網路檔案館）提供了類似功能。該實現與 `/dev/random` 的功能和介面類似，即建立了兩個裝置，RANDOM$ 與 URANDOM$，也可以通過 / DEV/RANDOM$ 和 / DEV/URANDOM$ 存取。

## EGD

EGD（熵收集守護行程，Entropy Gathering Daemon）通常可以在不支援 `/dev/random` 裝置的 UNIX 系統中提供類似的功能。這是一個執行於使用者態的守護行程，提供了高品質的密碼用亂數據。一些加密軟體，例如 OpenSSL，GNU Privacy Guard 和 Apache HTTP 伺服器支援在 `/dev/random` 不可用的時候使用 EGD。

EGD（頁面存檔備份，存於網際網路檔案館），或者類似的軟體，例如 prngd（頁面存檔備份，存於網際網路檔案館），可以從多種來源收集偽隨機的熵，並對這些資料進行處理以去除偏置，並改善密碼學品質，然後允許其它程式通過 UNIX 域套介面（通常使用 **`/dev/egd-pool`**），或 TCP 套介面存取其輸出。該程式通常使用建立子行程的以查詢系統狀態的方式來收集熵。它查詢的狀態通常是易變的、不可預測的，例如 CPU、I/O、網路的使用率，也可能是一些紀錄檔檔案和臨時目錄中的內容。

## 參考文獻

* Biege, Thomas; Analysis of a strong Random Number Generator Slides

## 參見

* Unix 哲學
* 標準流
* /dev/full
* /dev/null
* /dev/zero
* /dev
* 硬體亂數生成器
* 密碼學安全偽亂數生成器
* Yarrow 演算法
* Fortuna 演算法
/dev/random