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