91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解PHP中的隨機數安全問題

發布時間:2021-10-11 16:44:13 來源:億速云 閱讀:146 作者:柒染 欄目:網絡安全

這期內容當中小編將會給大家帶來有關如何理解PHP中的隨機數安全問題,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1、引言

西湖論劍杯線上預選賽線上賭場一題,明文攻擊出來的hint中給了/flag/seed.txt以及一個字符串code,這里需要稍微腦洞一點想到seed是指隨機數種子,以及Web頁面上的code值是每小時更換的"隨機數":

如何理解PHP中的隨機數安全問題

我們利用phpmtseed工具(C編寫,速度很快)可以根據隨機數碰撞出隨機數的種子,從而獲取flag:

如何理解PHP中的隨機數安全問題

以下是原理分析:

2、隨機數的安全缺陷

隨機數廣泛應用于生成驗證碼、Token、密鑰等場景中,分為真隨機數和偽隨機數。我們通過算法(常用線性同余)和種子(常用時鐘)得到的隨機數屬于偽隨機數:當知道種子或已產生的隨機數時,隨機數序列是可以被預測的。

如何理解PHP中的隨機數安全問題

可以看到PHP Manual其實提示了生成隨機數用于加密是不安全的,但是這個Caution不知為何只存在于英文版的PHP Manual中,中文版被遺漏了...這可能也是很多國內的開發應用出現過此缺陷的一個原因。

PHP中生成隨機數的函數有rand()和mtrand(),它們分別對應srand()和mtstrand()兩個用于播種隨機數種子的函數。我們建立rand.php進行測試:


  1. <?php

  2. mt_srand(2333);

  3. srand(2333);

  4. echo "seed=2333,rand()產生的隨機數序列:\n";

  5. for($i=1;$i<=3;$i++){

  6.   echo rand()."\n";

  7. }

  8. echo "seed=2333,mt_rand()產生的隨機數序列:\n";

  9. for($i=1;$i<=3;$i++){

  10.   echo mt_rand()."\n";

  11. }

  12. ?>

執行:


如何理解PHP中的隨機數安全問題

可以看出當隨機數種子相同時,不管是rand()還是mtrand()產生的隨機數序列都是相同的,如果seed泄露則會導致隨機數序列的泄露。當種子值為固定如mtsrand(1000)時,隨機數形同虛設;而使用動態種子也未必安全,如:


  1. //seed值較小,直接遍歷爆破

  2. mt_srand(mt_rand(0,1000));

  3. //用公開的time()作為種子,和靜態種子一樣危險

  4. mt_srand(time());

  5. //破解時要注意服務器時間可能存在偏差,需要設定一個較小的范圍

自PHP 4.2.0 起,隨機數發生器會自動完成播種,不再需要手工調用srand()或mt_srand(),但是這樣仍舊不安全,我們分別對兩個函數進行討論

3、rand()

rand()在產生隨機數時不會自動調用srand(),產生的隨機數序列可以通過這個式子預測:

state[i] = state[i-3] + state[i-31]

所以我們可以收集rand()生成的32位以上的隨機序列,以預測后面的隨機序列。

詳細參考:Cracking-Php-Rand

(http://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/)

并且在某些平臺下rand()最大值為32767,非常容易遭到爆破。

4、mt_rand()

根據PHP Manual,mtrand()產生隨機數值的平均速度比libc提供的rand()快四倍,rand() 函數默認使用 libc 隨機數發生器,mtrand() 函數是非正式用來替換它的。

mtrand()函數的安全缺陷主要出現在,所謂"自動播種"其實是PHP在同一個請求進程中只會進行一次播種,也就是說即使多次調用mtrand()函數,也只會根據第一次播種的種子生成隨機數。這一結論的證明可以通過mt_rand()的源碼分析或寫個小腳本測試來完成,不再展開,函數的核心實現代碼是這一部分:


  1. PHPAPI void php_mt_srand(uint32_t seed)

  2. {

  3.    /* Seed the generator with a simple uint32 */

  4.    php_mt_initialize(seed, BG(state));

  5.    php_mt_reload();

  6.    /* Seed only once */

  7.    BG(mt_rand_is_seeded) = 1;

  8. }

  9. /* }}} */

  10. /* {{{ php_mt_rand

  11. */

  12. PHPAPI uint32_t php_mt_rand(void)

  13. {

  14.    /* Pull a 32-bit integer from the generator state

  15.       Every other access function simply transforms the numbers extracted here */

  16.    register uint32_t s1;

  17.     if (UNEXPECTED(!BG(mt_rand_is_seeded))) {

  18.        php_mt_srand(GENERATE_SEED());

  19.    }

  20.    if (BG(left) == 0) {

  21.        php_mt_reload();

  22.    }

  23.    --BG(left);

  24.    s1 = *BG(next)++;

  25.    s1 ^= (s1 >> 11);

  26.    s1 ^= (s1 <<  7) & 0x9d2c5680U;

  27.    s1 ^= (s1 << 15) & 0xefc60000U;

  28.    return ( s1 ^ (s1 >> 18) );

  29. }

由于根據種子生成隨機數序列的計算并不可逆,有效的破解方法應該是窮舉種子并生成隨機數序列,與已知的隨機數(序列)作比較,這也是文章開頭提到的phpmtseed工具的實現邏輯。

5、安全建議

涉及到加密/權限/CSRF Token等敏感操作時:

  • 不要使用時間函數作為種子或直接作為隨機數:time()/microtime()

  • 不要直接使用rand()``mt_rand()這樣的弱偽隨機數生成器

  • 隨機數要足夠長以防御暴力破解

上述就是小編為大家分享的如何理解PHP中的隨機數安全問題了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

九寨沟县| 甘孜县| 东安县| 开鲁县| 通化市| 澳门| 大埔县| 田林县| 抚顺县| 盘山县| 临澧县| 柯坪县| 南漳县| 凤城市| 雅江县| 鲁山县| 昂仁县| 荆门市| 蕲春县| 佛冈县| 临泽县| 华宁县| 洛南县| 油尖旺区| 东丰县| 蚌埠市| 安吉县| 济阳县| 新邵县| 商城县| 嫩江县| 黄骅市| 那坡县| 东乌珠穆沁旗| 靖州| 麻江县| 五莲县| 保定市| 曲靖市| 达拉特旗| 吉木萨尔县|