php中的rand,预测PHP的rand()的输出
從中猜測下一個值的rand能力與確定所srand調用內容的能力有關。特別是,以預定數量播種會srand導致可預測的輸出!在PHP交互式提示符下:
[charles@charles-workstation ~]$ php -a
Interactive shell
php > srand(1024);
php > echo rand(1, 100);
97
php > echo rand(1, 100);
97
php > echo rand(1, 100);
39
php > echo rand(1, 100);
77
php > echo rand(1, 100);
93
php > srand(1024);
php > echo rand(1, 100);
97
php > echo rand(1, 100);
97
php > echo rand(1, 100);
39
php > echo rand(1, 100);
77
php > echo rand(1, 100);
93
php >
這不僅僅是fl幸。大多數PHP版本*在大多數平臺**會生成序列97,97,39,77,93時,srand“d與1024。
要明確的是,這不是PHP的問題,這是其rand自身實現的問題。在使用相同(或相似)實現的其他語言(包括Perl)中也會出現相同的問題。
訣竅是,任何理智的PHP版本都將預先植入srand“未知”值。哦,但這并不是真正未知的。來自ext/standard/php_rand.h:
#defineGENERATE_SEED()(((long)(time(0)*getpid()))^((long)(1000000.0*php_combined_lcg(TSRMLS_C))))
因此,這是一個數學運算符time(),其中包含PID以及PID的結果php_combined_lcg,它們在中定義ext/standard/lcg.c。我不會在這里進行c&p,因為,我的眼睛發呆,所以我決定停止狩獵。
有點谷歌搜索表明PHP的其他區域沒有最好的隨機性生成屬性,并呼吁在php_combined_lcg這里脫穎而出,尤其是以下分析:
此函數(gettimeofday)不僅使我們在銀盤上獲得了精確的服務器時間戳,而且如果我們要求“更多熵”(來自PHP uniqid),它還會添加LCG輸出。
是啊是uniqid。似乎值php_combined_lcg是在調用uniqid第二個參數設置為真值后查看生成的十六進制數字時所看到的。
現在,我們在哪里?
哦是的 srand。
因此,如果您嘗試從中預測隨機值的代碼沒有調用srand,則需要確定由提供的值php_combined_lcg,您可以通過調用來(間接獲得)該值uniqid。根據手中的價值,這是可行的,以蠻力價值的休息- time(),PID和一些數學。鏈接的安全性問題是關于中斷會話的,但是相同的技術在這里也適用。再次,從文章:
這是上面概述的攻擊步驟的摘要:
等待服務器重啟
獲取唯一值
蠻力從此RNG種子
輪詢在線狀態以等待目標出現
將狀態輪詢與uniqid輪詢交錯,以跟蹤當前服務器時間和RNG值
使用輪詢中建立的時間和RNG值間隔對服務器進行暴力會話ID
只需根據需要替換最后一步。
(此安全問題是在比我們當前的版本(5.3.6)更早的PHP版本(5.3.2)中報告的,因此,uniqid和/或php_combined_lcg已更改的行為很可能,因此該特定技術可能不再可行。 YMMV。)
另一方面,如果您要嘗試人工生成的代碼調用srand,那么除非它們使用的結果比的結果好很多倍,否則php_combined_lcg您可能會更容易地猜測出值并為本地設置種子編號正確的發電機。大多數會手動調用的人srand也不會意識到這是多么可怕的想法,因此不太可能使用更好的價值。
值得注意的是,mt_rand同樣的問題也困擾著它。mt_srand具有已知值的播種也會產生可預測的結果。基于您的熵openssl_random_pseudo_bytes可能是一個更安全的選擇。
tl; dr:為了獲得最佳結果,請不要植入PHP隨機數生成器,并且出于良善起見,請不要uniqid向用戶公開。兩者之一或兩者都做可能會使您的隨機數更容易猜測。
PHP 7更新:
PHP 7.0引入random_bytes和random_int作為核心功能。他們使用基礎系統的CSPRNG實現,從而使它們擺脫了種子隨機數生成器所具有的問題。它們實際上與相似openssl_random_pseudo_bytes,只是不需要安裝擴展程序。 Polyfill可用于PHP5。
*:Suhosin安全補丁會更改的行為,rand并mt_rand始終在每次調用時重新植入種子。Suhosin由第三方提供。默認情況下,某些Linux發行版將其包含在其官方PHP軟件包中,而其他發行版則將其作為選項,而其他發行版則完全忽略了它。
**:根據所使用的平臺和底層庫調用,將生成與此處記錄的序列不同的序列,但是除非使用Suhosin補丁,否則結果應仍可重復。
總結
以上是生活随笔為你收集整理的php中的rand,预测PHP的rand()的输出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java trackid_Java Pr
- 下一篇: php编程查错,盘点PHP编程常见失误