PHP中的隨機性——你覺得自己幸運嗎?_PHP教程

來源:互聯網
上載者:User

PHP中的隨機性——你覺得自己幸運嗎?


本文分析了產生用於加密的隨機數的相關問題。 PHP 5沒有提供一種簡單的機制來產生密碼學上強壯的隨機數,但是PHP 7通過引入幾個CSPRNG函數來解決了這個問題。

什麼是CSPRNG

引用維基百科,一個密碼學上安全的偽隨機數發生器Cryptographically Secure Pseudorandom Number Generator 縮寫CSPRNG)是一個偽隨機數產生器PRNG),其產生的偽隨機數適用於密碼學演算法。

CSPRNG可能主要用於:

  • 密鑰產生例如,產生複雜的密鑰)

  • 為新使用者產生隨機的密碼

  • 加密系統

獲得進階別安全性的一個關鍵方面就是高品質的隨機性

PHP7 中的CSPRNG

PHP 7引入了兩個新函數可以用來實現CSPRNG: random_bytes 和 random_int。

random_bytes 函數返回一個字串,接受一個int型入參代表返回結果的位元組數。

例子:

 
  1. $bytes = random_bytes('10');
  2. var_dump(bin2hex($bytes));
  3. //possible ouput: string(20) "7dfab0af960d359388e6"

random_int 函數返回一個指定範圍內的int型數字。

例子:

 
  1. var_dump(random_int(1, 100));
  2. //possible output: 27

後台運行環境

以上函數的隨機性不同的取決於環境:

  • 在window上,CryptGenRandom()總是被使用。

  • 在其他平台,arc4random_buf()如果可用會被使用在BSD系列或者具有libbsd的系統上成立)

  • 以上都不成立的話,一個linux系統調用getrandom(2)會被使用。

  • 如果還不行,/dev/urandom 會被作為最後一個可使用的工具

  • 如果以上都不行,系統會拋出錯誤

一個簡單的測試

一個好的隨機數產生系統保證合適的產生“品質”。為了檢查這個品質, 通常要執行一連串的統計測試。不需要深入研究複雜的統計主題,比較一個已知的行為和數字產生器的結果可以協助品質評價。

一個簡單的測試是骰子遊戲。假設擲1個骰子1次得到結果為6的機率是1/6,那麼如果我同時擲3個骰子100次,得到的結果粗略如下:

  • 0 個6 = 57.9 次

  • 1 個6 = 34.7次

  • 2 個6 = 6.9次

  • 3 個6 = 0.5次

以下是是實現實現擲骰子1,000,000次的代碼:

 
  1. $times = 1000000;
  2. $result = [];
  3. for ($i=0; $i<$times; $i++){
  4. $dieRoll = array(6 => 0); //initializes just the six counting to zero
  5. $dieRoll[roll()] += 1; //first die
  6. $dieRoll[roll()] += 1; //second die
  7. $dieRoll[roll()] += 1; //third die
  8. $result[$dieRoll[6]] += 1; //counts the sixes
  9. }
  10. function roll(){
  11. return random_int(1,6);
  12. }
  13. var_dump($result);

用PHP7 的 random_int 和簡單的 rand 函數可能得到如下結果

Sixes

expected

random_int

0

579000

579430

1

347000

346927

2

69000

68985

3

5000

4658

如果先看到rand 和 random_int 更好的比較我們可以應用一個公式把結果畫在圖上。公式是:(php結果-期待的結果)/期待結果的0.5次方。

結果圖如下:

接近0的值更好)

儘管3個6的結果表現不好,並且這個測試對實際應用來說太過簡單我們仍可以看出 random_int 表現優於 rand.

進一步,我們的應用的安全層級由於不可預測性和隨機數發生器的可重複行為而得到提升。

PHP5 呢

預設情況下,PHP5 不提供強壯的隨機數發生器。實際上,還是有選擇的比如 openssl_random_pseudo_bytes(), mcrypt_create_iv() 或者直接使用fread()函數來使用 /dev/random 或 /dev/urandom 裝置。也有一些包比如 RandomLib 或 libsodium.

如果你想要開始使用一個更好的隨機數發生器並且同時準備好使用PHP7,你可以使用Paragon Initiative Enterprises random_compat 庫。 random_compat 庫允許你在 PHP 5.x project.使用 random_bytes() and random_int()

這個庫可以通過Composer安裝:

 
  1. composer require paragonie/random_compat
  2. require 'vendor/autoload.php';
  3. $string = random_bytes(32);
  4. var_dump(bin2hex($string));
  5. // string(64) "8757a27ce421b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2aaec6f"
  6. $int = random_int(0,255);
  7. var_dump($int);
  8. // int(81)

random_compat 庫和PHP7使用不同的順序:

 
  1. fread() /dev/urandom if available
  2. mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)
  3. COM('CAPICOM.Utilities.1')->GetRandom()
  4. openssl_random_pseudo_bytes()

想知道為什麼是這個順序建議閱讀 documentation.

這個庫的一個簡單應用用來產生密碼:

 
  1. $passwordChar = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  2. $passwordLength = 8;
  3. $max = strlen($passwordChar) - 1;
  4. $password = '';
  5. for ($i = 0; $i < $passwordLength; ++$i) {
  6. $password .= $passwordChar[random_int(0, $max)];
  7. }
  8. echo $password;
  9. //possible output: 7rgG8GHu

總結

你總是應該使用一個密碼學上安全的偽隨機數產生器,random_compat 庫提供了一種好的實現。

如果你想要使用可靠的隨機資料來源,如你在本文所見,建議儘快使用 random_int 和 random_bytes.

譯文連結:http://www.codeceo.com/article/php-random.html
英文原文:Randomness in PHP – Do You Feel Lucky?

http://www.bkjia.com/PHPjc/1093808.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1093808.htmlTechArticlePHP中的隨機性——你覺得自己幸運嗎? 本文分析了產生用於加密的隨機數的相關問題。PHP5沒有提供一種簡單的機制來產生密碼學上強壯的...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.