自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux 系統(tǒng)中隨機(jī)數(shù)在 KVM 中的應(yīng)用

系統(tǒng) Linux
隨機(jī)數(shù)在計算機(jī)系統(tǒng)中處于非常重要的地位,如果沒有隨機(jī)數(shù),可能很多應(yīng)用都將陷入麻煩,隨機(jī)數(shù)在密碼學(xué)和安全領(lǐng)域也是至關(guān)重要。本文主要介紹隨機(jī)數(shù)的概念和重要性,Linux 系統(tǒng)中隨機(jī)數(shù)是如何產(chǎn)生的,最后介紹在 KVM 虛擬機(jī)中如何添加和使用硬件隨機(jī)數(shù)產(chǎn)生器來產(chǎn)生隨機(jī)數(shù)。

隨機(jī)數(shù)在計算機(jī)系統(tǒng)中處于非常重要的地位,如果沒有隨機(jī)數(shù),可能很多應(yīng)用都將陷入麻煩,隨機(jī)數(shù)在密碼學(xué)和安全領(lǐng)域也是至關(guān)重要。本文主要介紹隨機(jī)數(shù)的概念和重要性,Linux 系統(tǒng)中隨機(jī)數(shù)是如何產(chǎn)生的,最后介紹在 KVM 虛擬機(jī)中如何添加和使用硬件隨機(jī)數(shù)產(chǎn)生器來產(chǎn)生隨機(jī)數(shù)。

什么是隨機(jī)數(shù)

很多軟件和應(yīng)用都需要隨機(jī)數(shù),從紙牌游戲中紙牌的分發(fā)到 SSL 安全協(xié)議中密鑰的產(chǎn)生,到處都有隨機(jī)數(shù)的身影。隨機(jī)數(shù)至少具備兩個條件:

  1. 數(shù)字序列在統(tǒng)計上是隨機(jī)的
  2. 不能通過已知序列推算后面的序列

自從計算機(jī)誕生起,尋求用計算機(jī)產(chǎn)生高質(zhì)量的隨機(jī)數(shù)序列的研究就一直是研究者長期關(guān)注的課題。一般情況下,使用計算機(jī)程序產(chǎn)生一個真正的隨機(jī)數(shù)是很難的,因為程序的行為是可預(yù)測的,計算機(jī)利用設(shè)計好的算法結(jié)合用戶提供的種子產(chǎn)生的隨機(jī)數(shù)序列通常是“偽隨機(jī)數(shù)”(pseudo-random number),偽隨機(jī)數(shù)就是我們平時經(jīng)常使用的“隨機(jī)數(shù)”。偽隨機(jī)數(shù)可以滿足一般應(yīng)用的需求,但是在對于安全要求比較高的環(huán)境和領(lǐng)域中存在明顯的缺點:

  1. 偽隨機(jī)數(shù)是周期性的,當(dāng)它們足夠多時,會重復(fù)數(shù)字序列
  2. 如果提供相同的算法和相同的種子值,將會得出完全一樣的隨機(jī)數(shù)序列
  3. 可以使用逆向工程,猜測算法與種子值,以便推算后面所有的隨機(jī)數(shù)列

只有實際物理過程才是真正的隨機(jī),只有借助物理世界中事物的隨機(jī)性才能產(chǎn)生真正的隨機(jī)數(shù),比如真空內(nèi)亞原子粒子量子漲落產(chǎn)生的噪音、超亮發(fā)光二極管在噪聲的量子不確定性和放射性衰變等。

 

隨機(jī)數(shù)為什么如此重要

生成隨機(jī)數(shù)是密碼學(xué)中的一項基本任務(wù),是生成加密密鑰、加密算法和加密協(xié)議所必不可少的,隨機(jī)數(shù)的質(zhì)量對安全性至關(guān)重要。最近報道有人利用隨機(jī)數(shù)缺點成功攻擊了某網(wǎng)站,獲得了管理員的權(quán)限。美國和法國的安全研究人員最近也評估了兩個 Linux 內(nèi)核 PRNG——/dev/random 和/dev/urandom 的安全性,認(rèn)為 Linux 的偽隨機(jī)數(shù)生成器不滿足魯棒性的安全概念,沒有正確積累熵??梢婋S機(jī)數(shù)在安全系統(tǒng)中占據(jù)著非常重要的地位。

 

Linux 中隨機(jī)數(shù)如何產(chǎn)生

PRNG(Pseudo-Random Number Generator)

1994 年,美國軟件工程師 Theodore Y. Ts’o 第一次在 Linux 內(nèi)核中實現(xiàn)了隨機(jī)數(shù)發(fā)生器,使用 SHA-1 散列算法而非密碼,提高了密碼強(qiáng)度。

Linux 內(nèi)核采用熵來描述數(shù)據(jù)的隨機(jī)性,熵(entropy)是描述系統(tǒng)混亂無序程度的物理量,一個系統(tǒng)的熵越大則說明該系統(tǒng)的有序性越差,即不確定性越大。內(nèi)核維護(hù)了一個熵池用來收集來自設(shè)備驅(qū)動程序和其它來源的環(huán)境噪音。理論上,熵池中的數(shù)據(jù)是完全隨機(jī)的,可以實現(xiàn)產(chǎn)生真隨機(jī)數(shù)序列。為跟蹤熵池中數(shù)據(jù)的隨機(jī)性,內(nèi)核在將數(shù)據(jù)加入池的時候?qū)⒐浪銛?shù)據(jù)的隨機(jī)性,這個過程稱作熵估算。熵估算值描述池中包含的隨機(jī)數(shù)位數(shù),其值越大表示池中數(shù)據(jù)的隨機(jī)性越好。 內(nèi)核中隨機(jī)數(shù)發(fā)生器 PRNG 為一個字符設(shè)備 random,代碼實現(xiàn)在 drivers/char/random.c,該設(shè)備實現(xiàn)了一系列接口函數(shù)用于獲取系統(tǒng)環(huán)境的噪聲數(shù)據(jù),并加入熵池。系統(tǒng)環(huán)境的噪聲數(shù)據(jù)包括設(shè)備兩次中斷間的間隔,輸入設(shè)備的操作時間間隔,連續(xù)磁盤操作的時間間隔等。 對應(yīng)的接口包括:

  1. void add_device_randomness(const void *buf, unsigned int size); 
  2. void add_input_randomness(unsigned int type, unsigned int code, 
  3.                 unsigned int value); 
  4. void add_interrupt_randomness(int irq, int irq_flags); 
  5. void add_disk_randomness(struct gendisk *disk); 

內(nèi)核提供了 1 個的接口來供其他內(nèi)核模塊使用。

  1. void get_random_bytes(void *buf, int nbytes); 

該接口會返回指定字節(jié)數(shù)的隨機(jī)數(shù)。random 設(shè)備了提供了 2 個字符設(shè)備供用戶態(tài)進(jìn)程使用——/dev/random 和/dev/urandom:

  • /dev/random 適用于對隨機(jī)數(shù)質(zhì)量要求比較高的請求,在熵池中數(shù)據(jù)不足時, 讀取 dev/random 設(shè)備時會返回小于熵池噪聲總數(shù)的隨機(jī)字節(jié)。/dev/random 可生成高隨機(jī)性的公鑰或一次性密碼本。若熵池空了,對/dev/random 的讀操作將會被阻塞,直到收集到了足夠的環(huán)境噪聲為止。這樣的設(shè)計使得/dev/random 是真正的隨機(jī)數(shù)發(fā)生器,提供了最大可能的隨機(jī)數(shù)據(jù)熵。
  • /dev/urandom,非阻塞的隨機(jī)數(shù)發(fā)生器,它會重復(fù)使用熵池中的數(shù)據(jù)以產(chǎn)生偽隨機(jī)數(shù)據(jù)。這表示對/dev/urandom 的讀取操作不會產(chǎn)生阻塞,但其輸出的熵可能小于/dev/random 的。它可以作為生成較低強(qiáng)度密碼的偽隨機(jī)數(shù)生成器,對大多數(shù)應(yīng)用來說,隨機(jī)性是可以接受的。

/dev/random 也允許寫入,任何用戶都可以向熵池中加入隨機(jī)數(shù)據(jù)。即使寫入非隨機(jī)數(shù)據(jù)亦是無害的,因為只有管理員可以調(diào)用 ioctl 以增加熵池大小。Linux 內(nèi)核中當(dāng)前熵的值和大小可以通過訪問 /proc/sys/kernel/random/得到,比如:

  1. # cat /proc/sys/kernel/random/poolsize 
  2. 4096 
  3. # cat /proc/sys/kernel/random/entropy_avail 
  4. 298 
  5. # cat /proc/sys/kernel/random/uuid 
  6. 4f0683ae-6141-41e1-b5b9-57f4bd299219 

但是 Linux 內(nèi)核中隨機(jī)發(fā)生器中存在幾個弱點,在嵌入式系統(tǒng)(缺少鼠標(biāo)鍵盤),Live CD 系統(tǒng)(缺少磁盤),路由器,無盤工作站和一些服務(wù)器系統(tǒng)中,環(huán)境熵的來源較為受限,隨機(jī)數(shù)質(zhì)量會有所下降。對于有 NVRAM 的系統(tǒng),建議在關(guān)機(jī)時保存一部分隨機(jī)數(shù)發(fā)生器的狀態(tài),使得在下次開機(jī)時可以恢復(fù)這些狀態(tài)。對于路由器而言,可以考慮把網(wǎng)絡(luò)數(shù)據(jù)可以作為熵的主要來源。

EGD

EGD(熵收集守護(hù)進(jìn)程,entropy gathering daemon)通??梢栽诓恢С?dev/random 設(shè)備的 Unix 系統(tǒng)中提供類似的功能。這是一個運(yùn)行于用戶態(tài)的守護(hù)進(jìn)程,提供了高質(zhì)量的密碼用隨機(jī)數(shù)據(jù)。一些加密軟件,比如 OpenSSL,GNU Privacy Guard 和 Apache HTTP 服務(wù)器支持在/dev/random 不可用的時候使用 EGD。

EGD,或者類似的軟件 prngd,可以從多種來源收集偽隨機(jī)的熵,并對這些數(shù)據(jù)進(jìn)行處理以去除偏置,并改善密碼學(xué)質(zhì)量,然后允許其它程序通過 Unix 域套接口(通常使用/dev/egd-pool),或 TCP 套接口訪問其輸出。該程序通常使用建立子進(jìn)程的以查詢系統(tǒng)狀態(tài)的方式來收集熵。它查詢的狀態(tài)通常是易變和不可預(yù)測的,例如 CPU,I/O,網(wǎng)絡(luò)的使用率,也可能是一些日志文件和臨時目錄中的內(nèi)容。

EGD 通過一個簡單的協(xié)議與那些需要隨機(jī)數(shù)的客戶端進(jìn)行通信,客戶端通過連接 EGD socket 發(fā)送命令(從前八位來識別命令):

  • command 0: 查詢當(dāng)前可用熵
  • command 1: 非阻塞地獲取隨機(jī)字節(jié)數(shù)
  • command 2: 阻塞地獲取隨機(jī)字節(jié)數(shù)
  • command 3: 更新熵

硬件隨機(jī)數(shù)產(chǎn)生器

當(dāng)前有很多硬件隨機(jī)數(shù)產(chǎn)生器(hwrng)用于產(chǎn)生可靠的隨機(jī)數(shù),但都是商用的,價格比較昂貴,最常使用的是 ComScire QNG,截止筆者寫這篇文章,ComScire PQ4000KU 的官方價格接近 900 美元。

Intel’s Ivy Bridge family 有一個功能叫”Secure Key”, 處理器包含了一個內(nèi)部硬件 DRNG(Digital Random Number Generator)用于產(chǎn)生隨機(jī)數(shù),使用匯編指令 RDRAND 即可獲得高強(qiáng)度的隨機(jī)數(shù),Linux Kernel 會使用異或操作把 RDRAND 產(chǎn)生的隨機(jī)數(shù)混合進(jìn)熵池, 代碼實現(xiàn)在 drivers/char/random.c 的 extract_entropy()函數(shù)里。

  1. for (i = 0; i < LONGS(EXTRACT_SIZE); i++) { 
  2. unsigned long v; 
  3. if (!arch_get_random_long(&v)) 
  4. break; 
  5. hash.l[i] ^= v; 

還有一些第三方的硬件隨機(jī)數(shù)生成器,通常是 USB 或者 PCI 設(shè)備,主要是在服務(wù)器上使用。Linux Kernel 的 hwrng(hardware random number generator)抽象層(/dev/hwrng 設(shè)備)可以選擇監(jiān)控 RNG 設(shè)備,并且在熵池數(shù)據(jù)不足的時候要求設(shè)備提供隨機(jī)數(shù)據(jù)到 kernel 的熵池,rngd 守護(hù)進(jìn)程可以讀取 hwrng 的數(shù)據(jù)然后補(bǔ)給到 kernel 的熵池中。

 

在 KVM 虛擬機(jī)中如何應(yīng)用

虛擬機(jī)環(huán)境下和服務(wù)器情況類似,輸入設(shè)備操作很少,相對于 Host 而言,Disk I/O 也相對較少,因此依賴 Guest 自身 PRNG 產(chǎn)生的隨機(jī)數(shù)質(zhì)量不高,因此虛擬機(jī)通常從 Host(宿主機(jī))獲取部分隨機(jī)數(shù)據(jù)。對于 KVM 虛擬機(jī)來說,存在一個半虛擬化設(shè)備 virtio-rng 作為硬件隨機(jī)數(shù)產(chǎn)生器。Linux Kernel 從 2.6.26 開始支持 virtio-rng, QEMU 在 1.3 版本加入了對 virtio-rng 的支持。 virtio-rng 設(shè)備會讀取 Host 的隨機(jī)數(shù)源并且填充到 Guest(客戶機(jī))的熵池中。通常情況下使用/dev/random 作為輸入源。當(dāng)然,數(shù)據(jù)源可以更改,當(dāng) Host 系統(tǒng)中存在 hwrng 的情況下你可以使用/dev/hwrng 來作為 virtio-rng 的輸入源。 也可以把 hwrng 設(shè)備 pass-through(透傳)到客戶機(jī)中,但是并不實用,比如在虛擬機(jī) Live Migration(實時遷移)時會存在問題。在 Guest 中添加 virtio-rng 設(shè)備具體操作,使用/dev/random 作為輸入源,兩種方法:

  1. 使用 libvirt 編輯虛擬機(jī)的 XML 
  2. 在虛擬機(jī) XML 定義中,在&lt;devices&gt;段中添加: 
  3. &lt;rng model='virtio'&gt; 
  4. &lt;backend model='<strong>random</strong>'&gt;/dev/random&lt;/backend&gt; 
  5. &lt;/rng&gt; 
  6. 使用 QEMU command Line 直接添加: 
  7. -object <strong>rng-random</strong>,filename=/dev/random,id=rng0 \ 
  8. -device virtio-rng-pci,rng=rng0 

虛擬機(jī)啟動后,在 Host 端:

  1. $ lsof /dev/random 
  2. COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME 
  3. qemu-syst 23590 mars   11r   CHR    1,8      0t0 1032 /dev/random 
 

會看到當(dāng)前 QEMU 進(jìn)程正在使用/dev/random 設(shè)備。

  1. Guest 端: 
  2. $ cat /sys/devices/virtual/misc/hw_random/rng_available 
  3. virtio 
  4. $ cat /sys/devices/virtual/misc/hw_random/rng_current 
  5. virtio 
  6. $ lsmod | grep virtio_rng 
  7. virtio_rng  12790   0 
  8. .... 
 

可以看到 Guest 已經(jīng)識別到硬件隨機(jī)數(shù)產(chǎn)生器。

  1. $ dd if=/dev/hwrng of=/home/random-data bs=1 

添加 bs 選項并且最好設(shè)置的值比較小,因為 Host 上隨機(jī)數(shù)資源可能會比較少,如果 bs 設(shè)置值太大,短時間內(nèi)可能無法獲得足夠的數(shù)據(jù)寫入文件,同時在 Host 端多做一些鼠標(biāo)鍵盤或者磁盤的操作,會更快地產(chǎn)生隨機(jī)數(shù)。

  1. $ hexdump /home/random-data 
  2. 00000000    9501 e702 .... 
  3. 00000010    .... .... .... 
 

使用 EGD 協(xié)議來作為輸入源:

  1. 使用 libvirt 編輯虛擬機(jī)的 XML: 
  2. &lt;rng model='virtio'&gt; 
  3.    &lt;backend model='<strong>egd</strong>' type='tcp'&gt; 
  4.      &lt;source mode='connect' host='127.0.0.1' service='8000'/&gt; 
  5.    &lt;/backend&gt; 
  6.  &lt;/rng&gt; 
  7. 使用 QEMU command Line 直接添加: 
  8. -chardev socket,host=localhost,port=1024,id=chr0 \ 
  9. -object <strong>rng-egd</strong>,chardev=chr0,id=rng0 \ 
  10. -device virtio-rng- pci,rng=rng0 
 

總結(jié)

隨機(jī)數(shù)在計算機(jī)系統(tǒng)中有著非常重要的作用,本文闡述了隨機(jī)數(shù)的概念和重要性,介紹了在 Linux 中產(chǎn)生隨機(jī)數(shù)的方法,以及在 KVM 環(huán)境下虛擬機(jī)如何使用 virtio-rng 來獲取隨機(jī)數(shù)據(jù)。

責(zé)任編輯:黃丹 來源: IBM
相關(guān)推薦

2021-06-01 22:31:57

區(qū)塊鏈隨機(jī)數(shù)技術(shù)

2023-01-03 07:49:45

Java隨機(jī)數(shù)線程

2012-03-22 09:31:14

Java

2015-10-13 10:00:58

Swift隨機(jī)數(shù)使用總結(jié)

2010-09-06 17:40:59

SQL函數(shù)

2024-01-25 11:32:21

2019-09-11 10:09:00

Java虛擬機(jī)算法

2010-03-11 12:48:25

Python生成隨機(jī)數(shù)

2012-07-05 09:52:06

EFS文件加密

2024-11-01 15:51:06

2021-12-27 09:31:20

HashtableJava隨機(jī)數(shù)

2011-04-14 11:19:14

MySQL

2011-07-08 15:11:03

JAVA

2010-10-09 15:35:25

MySQL rand函

2010-03-22 19:41:31

2017-05-29 09:56:25

2009-07-06 15:11:18

Java 隨機(jī)數(shù)

2009-06-11 15:16:18

不重復(fù)隨機(jī)數(shù)Java

2009-12-08 11:44:14

PHP獲取隨機(jī)數(shù)

2009-12-08 12:58:33

PHP隨機(jī)數(shù)類
點贊
收藏

51CTO技術(shù)棧公眾號