如何理解PHP中的随机数安全问题


这期内容当中小编将会给大家带来有关如何理解PHP中的随机数安全问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、引言西湖论剑杯线上预选赛线上赌场一题,明文攻击出来的hint中给了/flag/seed.txt以及一个字符串code,这里需要稍微脑洞一点想到seed是指随机数种子,以及Web页面上的code值是每小时更换的”随机数”:
我们利用phpmtseed工具(C编写,速度很快)可以根据随机数碰撞出随机数的种子,从而获取flag:以下是原理分析:2、随机数的安全缺陷随机数广泛应用于生成验证码、Token、密钥等场景中,分为真随机数和伪随机数。我们通过算法(常用线性同余)和种子(常用时钟)得到的随机数属于伪随机数:当知道种子或已产生的随机数时,随机数序列是可以被预测的。
可以看到PHPManual其实提示了生成随机数用于加密是不安全的,但是这个Caution不知为何只存在于英文版的PHPManual中,中文版被遗漏了…这可能也是很多国内的开发应用出现过此缺陷的一个原因。PHP中生成随机数的函数有rand()和mtrand(),它们分别对应srand()和mtstrand()两个用于播种随机数种子的函数。我们建立rand.php进行测试mt_srand(2333);srand(2333);echo"seed=2333,rand()产生的随机数序列:n";for($i=1;$i echo rand()."n";}echo"seed=2333,mt_rand()产生的随机数序列:n";for($i=1;$i echo mt_rand()."n";}?>执行:

可以看出当随机数种子相同时,不管是rand()还是mtrand()产生的随机数序列都是相同的,如果seed泄露则会导致随机数序列的泄露。当种子值为固定如mtsrand(1000)时,随机数形同虚设;而使用动态种子也未必安全,如://seed值较小,直接遍历爆破mt_srand(mt_rand(0,1000));//用公开的time()作为种子,和静态种子一样危险mt_srand(time());//破解时要注意服务器时间可能存在偏差,需要设定一个较小的范围自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()的源码分析或写个小脚本测试来完成,不再展开,函数的核心实现代码是这一部分: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 s1 ^= (s1 return ( s1 ^ (s1 >> 18) );}由于根据种子生成随机数序列的计算并不可逆,有效的破解方法应该是穷举种子并生成随机数序列,与已知的随机数(序列)作比较,这也是文章开头提到的phpmtseed工具的实现逻辑。5、安全建议涉及到加密/权限/CSRFToken等敏感操作时:不要使用时间函数作为种子或直接作为随机数:time()/microtime()不要直接使用rand()“mt_rand()这样的弱伪随机数生成器随机数要足够长以防御暴力破解上述就是小编为大家分享的如何理解PHP中的随机数安全问题了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注云编程开发博客行业资讯频道。

相关推荐: 监控利器–Cacti

一、cacti概述 1.1 cacti是用php语言实现的一个软件,它的主要功能是用snmp服务获取数据,然后用rrdtool储存和更新数据,当用户需要查看数据的时候用rrdtool生成图表呈现给用户。因此,snmp和rrdtool是cacti的关键。Snmp…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 02/02 16:30
下一篇 02/02 16:30