[web 安全] php随机数安全问题

and() 和 mt_rand() 产生随机数
srand() 和 mt_srand() 播种随机数种子(seed)
使用:

<?php
srand(123);//播种随机数种子
for($i=0; $i<5; $i++){
echo rand()."\n";//产生随机数
}
?>

随机数种子一样,随机数序列则会完全一相同。

所以知道随机数种子后,就能知道所有随机数序列。(随机数种子 => 随机数序列)

知道随机数后,也能推出随机数种子。(随机数 => 随机数种子 => 随机数序列)

<?php
/* 通过随机数反推随机数种子 */
srand(123); $_rand = rand(); echo "rand:{$_rand}\n"; $max = mt_getrandmax(); for ($i=0; $i < $max; $i++) { srand($i); if(rand() == $_rand){ echo "rand seed:{$i}\n"; break; } } ?>

《白帽子讲 web 安全》:

在 php 5.2.1 及其之后的版本中调整了随机数的生成算法,但强度未变,因此在猜解种子时应在对应的php版本中进行。

在 Stefan Esser 的文中还提到一个小技巧,可以通过发送 Keep-Alive HTTP头,迫使服务器端使用同一PHP进程相应请求,而在该PHP进程中,

随机数在使用时只会在一开始播种一次。

《聊一聊随机数安全》:

int rand(void)
int rand(int $min, int $max)
如果没有提供参数min,max,rand()返回0到getrandmax()之间的伪随机整数,但是getrandmax()在window下返回32767,也就是window下rand()的范围是0到32767
mt_rand()对应的是mt_getrandmax(),返回2147483647。

安全建议:

1、业务场景需要使用随机数,一定要使用随机数,比如Token的生成。
2、随机数要足够长,避免暴力破解。
3、保证不同用处的随机数使用不同的种子,避免通过随机数推出随机数种子,从而得到随机数序列。
4、对安全性要求高的随机数(如密码技术相关)禁止使用弱伪随机数(mt_rand()比rand()强)。
  4.1 不要使用时间函数作为随机数。
  4.2 不要使用弱伪随机数生成器(rand()范围小;mt_rand()存在缺陷)。

5、强伪随机数

 

posted @ 2017-10-09 14:53  S3c0ldW4ng  阅读(395)  评论(0编辑  收藏  举报