久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

深入理解PHP中mt_rand()隨機數的安全

mt_rand()使用mersennetwister算法返回隨機整數,這個大家都知道,但下面這篇文章主要給大家介紹的是關于PHP中mt_rand()隨機數安全的相關資料,文中介紹的非常詳細,需要的朋友可以參考借

前言

在前段時間挖了不少跟mt_rand()相關的安全漏洞,基本上都是錯誤理解隨機數用法導致的。這里又要提一下php官網manual的一個坑,看下關于mt_rand()的介紹:中文版^cn 英文版^en,可以看到英文版多了一塊黃色的 Caution 警告

This function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using random_int(), random_bytes(), or openssl_random_pseudo_bytes() instead.

很多國內開發者估計都是看的中文版的介紹而在程序中使用了mt_rand()來生成安全令牌、核心加解密key等等導致嚴重的安全問題。

偽隨機數

mt_rand()并不是一個 真·隨機數 生成函數,實際上絕大多數編程語言中的隨機數函數生成的都都是偽隨機數。關于真隨機數和偽隨機數的區別這里不展開解釋,只需要簡單了解一點

偽隨機是由可確定的函數(常用線性同余),通過一個種子(常用時鐘),產生的偽隨機數。這意味著:如果知道了種子,或者已經產生的隨機數,都可能獲得接下來隨機數序列的信息(可預測性)。

簡單假設一下 mt_rand()內部生成隨機數的函數為: rand = seed+(i*10) 其中 seed 是隨機數種子, i 是第幾次調用這個隨機數函數。當我們同時知道 i 和 rand 兩個值的時候,就能很容易的算出seed的值來。比如 rand=21 , i=2 代入函數 21=seed+(2*10) 得到 seed=1 。是不是很簡單,當我們拿到seed之后,就能計算出當 i 為任意值時候的 rand 的值了。

PHP的自動播種

從上一節我們已經知道每一次mt_rand()被調用都會根據seed和當前調用的次數i來計算出一個偽隨機數。而且seed是自動播種的:

Note: 自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 給隨機數發生器播種 ,因為現在是由系統自動完成的。

那么問題就來了,到底系統自動完成播種是在什么時候,如果每次調用mt_rand()都會自動播種那么破解seed也就沒意義了。關于這一點manual并沒有給出詳細信息。網上找了一圈也沒靠譜的答案 只能去翻源碼^mtrand了:

PHPAPI void php_mt_srand(uint32_t seed)
{
 /* Seed the generator with a simple uint32 */
 php_mt_initialize(seed, BG(state));
 php_mt_reload();

 /* Seed only once */
 BG(mt_rand_is_seeded) = 1; 
}
/* }}} */

/* {{{ php_mt_rand
 */
PHPAPI uint32_t php_mt_rand(void)
{
 /* Pull a 32-bit integer from the generator state
 Every other access function simply transforms the numbers extracted here */

 register uint32_t s1;

 if (UNEXPECTED(!BG(mt_rand_is_seeded))) {
 php_mt_srand(GENERATE_SEED());
 }

 if (BG(left) == 0) {
 php_mt_reload();
 }
 --BG(left);

 s1 = *BG(next)++;
 s1 ^= (s1 >> 11);
 s1 ^= (s1 << 7) & 0x9d2c5680U;
 s1 ^= (s1 << 15) & 0xefc60000U;
 return ( s1 ^ (s1 >> 18) );
}

可以看到每次調用mt_rand()都會先檢查是否已經播種。如果已經播種就直接產生隨機數,否則調用php_mt_srand來播種。也就是說每個php cgi進程期間,只有第一次調用mt_rand()會自動播種。接下來都會根據這個第一次播種的種子來生成隨機數。而php的幾種運行模式中除了CGI(每個請求啟動一個cgi進程,請求結束后關閉。每次都要重新讀取php.ini 環境變量等導致效率低下,現在用的應該不多了)以外,基本都是一個進程處理完請求之后standby等待下一個,處理多個請求之后才會回收(超時也會回收)。

寫個腳本測試一下

<?php
//pid.php
echo getmypid();
<?php
//test.php
$old_pid = file_get_contents('http://localhost/pid.php');
$i=1;
while(true){
 $i++;
 $pid = file_get_contents('http://localhost/pid.php');
 if($pid!=$old_pid){
 echo $i;
 break;
 }
}

測試結果:(windows+phpstudy)

apache 1000請求

nginx 500請求

當然這個測試僅僅確認了apache和nginx一個進程可以處理的請求數,再來驗證一下剛才關于自動播種的結論:

<?php
//pid1.php
if(isset($_GET['rand'])){
 echo mt_rand();
}else{
 echo getmypid();
}
<?php
//pid2.php
echo mt_rand();
<?php
//test.php
$old_pid = file_get_contents('http://localhost/pid1.php');
echo "old_pid:{$old_pid}\r\n";
while(true){
 $pid = file_get_contents('http://localhost/pid1.php');
 if($pid!=$old_pid){
 echo "new_pid:{$pid}\r\n";
 for($i=0;$i<20;$i++){
  $random = mt_rand(1,2);
  echo file_get_contents("http://localhost/pid".$random.".php?rand=1")." ";
 }

 break;
 }
}
【網站聲明】本站除付費源碼經過測試外,其他素材未做測試,不保證完整性,網站上部分源碼僅限學習交流,請勿用于商業用途。如損害你的權益請聯系客服QQ:2655101040 給予處理,謝謝支持。

相關文檔推薦

這篇文章主要介紹了PHP有序表查找之插值查找算法,簡單分析了插值查找算法的概念、原理并結合實例形式分析了php實現針對有序表插值查找的相關操作技巧,需要的朋友可以參考下
下面小編就為大家分享一篇ThinkPHP整合datatables實現服務端分頁的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
下面小編就為大家分享一篇PHP實現APP微信支付的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
這篇文章主要介紹了PHP實現的多維數組排序算法,結合實例形式對比分析了php針對多維數組及帶有鍵名的多維數組進行排序相關操作技巧與注意事項,需要的朋友可以參考下
這篇文章主要為大家詳細介紹了php結合ajaxuploadfile實現無刷新文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本篇文章給大家詳細介紹了PHP開發接口使用RSA進行加密解密方法,對此有興趣的朋友可以學習下。
主站蜘蛛池模板: 高清人人天天夜夜曰狠狠狠狠 | 91国语清晰打电话对白 | 亚洲成人一区二区 | 天天天久久久 | 国产精品久久久 | 偷拍亚洲色图 | 欧美国产日韩在线 | 欧美一级片在线观看 | 日韩一区精品 | 亚洲欧美日韩中文在线 | 雨宫琴音一区二区在线 | 蜜桃毛片 | 欧美黑人巨大videos精品 | 中文字幕一区二区三区乱码在线 | 中文字幕第90页 | 国产精品一区二区在线 | 逼逼网| 国产目拍亚洲精品99久久精品 | 久久一级大片 | 欧美一区二区 | 黄色大片免费看 | 九九热精品在线 | 日韩三区在线观看 | 亚洲视频在线一区 | 精品久久国产老人久久综合 | 成人a在线观看 | 国产一级片av| 欧美精品一区二区在线观看 | 毛片免费视频 | 午夜三级视频 | 日韩视频免费看 | 精品少妇一区二区三区在线播放 | 午夜视频在线免费观看 | 久久精品国产免费 | 亚洲日韩欧美一区二区在线 | 欧美a级成人淫片免费看 | 中文字幕国产一区 | 国产福利二区 | 日一区二区 | 久久久免费少妇高潮毛片 | 成人av高清 |