摘要:本文主要分析以加密為目的的隨機數生成問題。一個簡例一個好的隨機數生成系統能確保生成質量適合的隨機數。此處,暫不深入討論復雜的統計話題,將已知的行為與隨機數生成器的結果進行比較,有助于質量評估。
本文主要分析以加密為目的的隨機數生成問題。PHP 5 并未提供生成強加密隨機數的簡便機制,但是,PHP 7 引入了兩個 CSPRNG 函數以解決該問題。系 OneAPM 工程師編譯整理。
什么是 CSPRNG?引用維基百科的定義,密碼安全的虛擬隨機數生成器(Cryptographically Secure Pseudorandom Number Generator,CSPRNG)是帶有特定屬性使之在密碼學中適用的虛擬隨機數生成器(pseudo-random number generator,PRNG)。
CSPRNG 主要用于:
生成鍵(比如:生成復雜的鍵)
為新的用戶賬號生成隨機密碼
加密系統
保證高安全水準的一個重要因素便是高質量的隨機數。
PHP 7 中的 CSPRNGPHP 7 為 CSPRNG 引入了兩種新函數:random_bytes 與 random_int。
random_bytes 函數返回 string 類型,并接受一個 int 類型為參數,該參數規定了所返回字符串的字節長度。
例如:
$bytes = random_bytes("10"); var_dump(bin2hex($bytes)); //possible ouput: string(20) "7dfab0af960d359388e6"
random_int 函數返回給定范圍內的整型數字。
舉例:
var_dump(random_int(1, 100)); //possible output: 27幕后解密
以上函數的隨機數來源因環境不同而有所差異:
在 Windows 系統,會使用 CryptGenRandom() 函數。
在其他平臺,會優先使用 arc4random_buf() 函數(限 BSD 衍生系統或帶 libbsd 的系統)。
若以上兩點均不符合,會使用 Linux getrandom(2) 系統調用。
若以上來源均不符合,會拋出 Error。
一個簡例一個好的隨機數生成系統能確保生成質量適合的隨機數。為了檢驗質量,需要運行一系列的統計試驗。此處,暫不深入討論復雜的統計話題,將已知的行為與隨機數生成器的結果進行比較,有助于質量評估。
一個簡單的測試方法是擲骰游戲。假設投擲一次,投出6的概率是1/6。如果同時投擲三個骰子,投100次,投得零次、一次、兩次及三次6的次數大概是:
0 次6 = 57.9 次
1 次6 = 34.7 次
2 次6 = 6.9 次
3 次6 = 0.5 次
以下是骰子投擲100萬次的代碼:
$times = 1000000; $result = []; for ($i=0; $i<$times; $i++){ $dieRoll = array(6 => 0); //initializes just the six counting to zero $dieRoll[roll()] += 1; //first die $dieRoll[roll()] += 1; //second die $dieRoll[roll()] += 1; //third die $result[$dieRoll[6]] += 1; //counts the sixes } function roll(){ return random_int(1,6); } var_dump($result);
用 PHP 7 的 random_int 與簡單的 rand 函數測試上面的代碼,可能會得到:
Sixes | expected | random_int | rand |
---|---|---|---|
0 | 579000 | 579430 | 578179 |
1 | 347000 | 346927 | 347620 |
2 | 69000 | 68985 | 69586 |
3 | 5000 | 4658 | 4615 |
更直觀地查看 rand 與 random_int 的差別,可以運用方程式放大兩組結果的差異,并繪制成圖表:
php result - expected result / sqrt(expected)
得到的結果如下:
(結果越接近零越好)
即便三個6的組合表現一般,且該測試與真實應用相比太過簡單,我們也能清楚地看到 random_int 的表現優于 rand。況且,隨機數生成器的可預見行為、重復行為越少,應用的安全程度就更高。
PHP 5 又如何呢?默認情況下,PHP 5 并未提供任何強虛擬隨機數生成器。而實際使用中,可以使用 openssl_random_pseudo_bytes()、mcrypt_create_iv() 方法,或直接結合使用 /dev/random 或 /dev/urandom 與 fread() 方法。此外,還有包 RandomLib 或 libsodium。
如果你想用一個比較好的隨機數生成器,同時能與 PHP 7 兼容,你可以使用 Paragon Initiative 公司的 random_compat 庫。該庫允許在 PHP 5.x 項目中使用 random_bytes() 與 random_int() 方法。
該庫可以使用 Composer 進行安裝:
composer require paragonie/random_compat
require "vendor/autoload.php"; $string = random_bytes(32); var_dump(bin2hex($string)); // string(64) "8757a27ce421b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2aaec6f" $int = random_int(0,255); var_dump($int); // int(81)
該 random_compat 庫使用了與 PHP 7 中不同的優先序列:
如果可用,先使用 fread() /dev/urandom
mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)
COM("CAPICOM.Utilities.1")->GetRandom()
openssl_random_pseudo_bytes()
想了解為何采用這一優先序列,可以閱讀本文檔。
使用該庫生成密碼的簡單案例如下:
$passwordChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; $passwordLength = 8; $max = strlen($passwordChar) - 1; $password = ""; for ($i = 0; $i < $passwordLength; ++$i) { $password .= $passwordChar[random_int(0, $max)]; } echo $password; //possible output: 7rgG8GHu總結
你應該盡量使用在密碼學上安全的虛擬隨機數生成器。random_compat 庫為此提供了很好的實現方法。
如果你想使用可靠的隨機數來源,正如前文所述,盡快開始使用 random_int 與 random_bytes 吧!
原文地址:http://www.sitepoint.com/randomness-php-feel-lucky/
OneAPM for PHP 能夠深入到所有 PHP 應用內部完成應用性能管理 能夠深入到所有 PHP 應用內部完成應用性能管理和監控,包括代碼級別性能問題的可見性、性能瓶頸的快速識別與追溯、真實用戶體驗監控、服務器監控和端到端的應用性能管理。想閱讀更多技術文章,請訪問 OneAPM 官方技術博客。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21278.html
摘要:本文分析了生成用于加密的隨機數的相關問題。沒有提供一種簡單的機制來生成密碼學上強壯的隨機數,但是通過引入幾個函數來解決了這個問題。呢缺省情況下,不提供強壯的隨機數發生器。如果你想要使用可靠的隨機數據源,如你在本文所見,建議盡快使用和 本文分析了生成用于加密的隨機數的相關問題。 PHP 5沒有提供一種簡單的機制來生成密碼學上強壯的隨機數,但是PHP 7通過引入幾個CSPRNG函數來解決了...
摘要:本文分析了生成用于加密的隨機數的相關問題。沒有提供一種簡單的機制來生成密碼學上強壯的隨機數,但是通過引入幾個函數來解決了這個問題。呢缺省情況下,不提供強壯的隨機數發生器。如果你想要使用可靠的隨機數據源,如你在本文所見,建議盡快使用和 本文分析了生成用于加密的隨機數的相關問題。 PHP 5沒有提供一種簡單的機制來生成密碼學上強壯的隨機數,但是PHP 7通過引入幾個CSPRNG函數來解決了...
摘要:使用微信企業號回調的坑最近在做企業號回調的接口,之前做過幾個企業號的應用了,每次接入到都報各種各樣的錯誤,算哥倒霉,該踩的不該踩的坑全踩了。 ThinkPHP 使用微信企業號回調的坑 最近在做企業號回調的接口,之前做過幾個企業號的應用了,每次接入到Thinkphp都報各種各樣的錯誤,算哥倒霉,該踩的不該踩的坑全踩了。 這次掉坑里差點就放棄了,開發過企業號的都知道,企業號回調會經過一個...
摘要:我們再來看國內一線公司內的一個實驗吧數據訓練營都在用的方法,詳解測試的那些坑如上是不同的引導卡片樣式的實驗,最終結果樣式比樣式的提升。設指標數值隱變量列顯變量列含方案變量。 作者|螞蟻金服人工智能部產品經理 范磊 本文首發|微信公眾號 友盟數據服務 (ID:umengcom),轉載請注明出處 If you are not running experiments,you are prob...
摘要:先來說說關鍵字。什么時候用來修飾方法關鍵字大家都知道是用來修飾方法與屬性的。一句話學會面向對象的方式來思考。充分發揮其性能優勢,又能解決擴展性差的問題。這里不會進行與的比較。 你以為你知道了一切,只是你以為而已。知識的美妙就在于,一生的時光在它面前顯得多么的短暫。 嗯嗯,扯遠了,我今天只想說說:static 與 yield。 先來說說 static 關鍵字。本篇只講靜態方法的使用與后期...
閱讀 2682·2021-11-16 11:53
閱讀 2745·2021-07-26 23:38
閱讀 2077·2019-08-30 15:55
閱讀 1758·2019-08-30 13:21
閱讀 3674·2019-08-29 17:26
閱讀 3313·2019-08-29 13:20
閱讀 882·2019-08-29 12:20
閱讀 3199·2019-08-26 10:21