Linux系統產生隨機數/dev/random 和 /dev/urandom

1.  基本介紹  

  /dev/random和/dev/urandom是Linux系統中提供的隨機僞設備,這兩個設備的任務,是提供永不爲空的隨機字節數據流。不少解密程序與安全應用程序(如SSH Keys,SSL Keys等)須要它們提供的隨機數據流。php

  這兩個設備的差別在於:/dev/random的random pool依賴於系統中斷,所以在系統的中斷數不足時,/dev/random設備會一直封鎖,嘗試讀取的進程就會進入等待狀態,直到系統的中斷數充分夠用, /dev/random設備能夠保證數據的隨機性。/dev/urandom不依賴系統的中斷,也就不會形成進程忙等待,可是數據的隨機性也不高。安全

  使用cat 命令能夠讀取/dev/random 和/dev/urandom的數據流(二進制數據流,很難閱讀),能夠用od命令轉換爲十六進制後查看:併發

  

  

在cat的過程當中發現,/dev/random產生的速度比較慢,有時候還會出現較大的停頓,而/dev/urandom的產生速度很快,基本沒有任何停頓。dom

而使用dd命令從這些設備中copy數據流,發現速度差別很大:ssh

從/dev/random中讀取1KB的字節流:函數

  

從/dev/urandom 中讀取1KB的字節流:測試

  

經過程序測試也發現:/dev/random設備被讀取的越多,它的響應越慢.加密

使用PHP的加密擴展mcrypt時,mcrypt_create_iv()函數用於從隨機源建立初始向量(initialization vector),該函數的簽名爲:code

string mcrypt_create_iv ( int $size [, int $source = MCRYPT_DEV_URANDOM ] )

注意函數的第二個參數$source,在PHP 5.6.0如下的版本中,該參數默認是  MCRYPT_DEV_RANDOM,也就是說,mcrypt_create_iv默認從/dev/random設備獲取隨機數據源的。這在系統併發數較高時,系統沒法提供足夠的中斷數,會致使訪問進程掛起(鎖住),從而沒法正常響應。進程

一個簡單的測試腳本以下:

1 <?php
2 define("MCRYPT_KEY","x90!-=zo2s");
3 $src = "test";
4 
5 $size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
6 $iv = mcrypt_create_iv($size);
7 $encrypted = mcrypt_ecb(MCRYPT_BLOWFISH, MCRYPT_KEY, $src, MCRYPT_DECRYPT, $iv);//5.5+已廢棄,請使用最新的API測試

咱們以前在cat /dev/random的輸出時已經發現,輸出的隨機數據流會出現較大的停頓。在併發數較大時,會形成讀取進程的等待甚至沒法響應。

幸虧,咱們能夠指定第二個參數爲MCRYPT_DEV_URANDOM使其強制使用/dev/urandom設備的隨機數據流(PHP 5.6.0+版本中,已經默認使用/dev/urandom做爲隨機數據源)。

2.   /dev/random和/dev/random的其餘用途

  1.  這兩個僞設備可用於代替mktemp產生隨機臨時文件名:

cat /dev/urandom |od –x | tr –d  ' '| head –n 1

  能夠產生128位(bit)的臨時文件名,具備較高的隨機性和安全性。

  2.  能夠模擬生成SSH-keygen生成的footprint,腳本以下:

 1 #/bin/sh -
 2 cat /dev/urandom |
 3 od -x |
 4 head -n 1|
 5 cut -d ' ' -f 2- |
 6 awk -v ORS=":" 
 7 '{
 8     for(i=1; i<=NF; i++){
 9         if(i == NF){
10             ORS = "\n";
11         }
12         print substr($i,1,2) ":" substr($i,3,2);
13     }
14 }'

對該腳本的簡單解釋:

  (1).  cat /dev/urandom | od -x  | head -n 1 用於從隨機設備中讀取一行數據流並轉換爲16進制。該段的輸出相似於:

    

  (2).  因爲第一列其實是數據的偏移量,並非隨機數據流,再次用cut取出後面的幾個字段:cut -d ' ' -f 2-

  (3).  利用awk程序輸出。ORS是awk的內置變量,指輸出記錄分割符,默認爲\n。

  腳本的輸出結果:

  

  對比用ssh-keygen生成的footprint,是否是挺像的? :D

  

相關文章
相關標籤/搜索