截断mt_rand()更安全吗?

时间:2013-04-28 10:37:49

标签: php c security random

我遇到过那些文章:

显示如何恢复mt_rand()函数的种子。附加的代码可以在一分钟(或更快)中从第一个mt_rand()强制种子。事实是,大多数PHP应用程序都使用带有范围参数的mt_rand。这会截断结果。我的问题是它是否更难破解?首先,我可以想象一个人只能用一个数字来强制它。他需要有一个完整的序列。它是否会使裂解过程显着延长或不重要? mt_rand(from, to)mt_rand()更安全吗?

1 个答案:

答案 0 :(得分:2)

Calling mt_rand($min, $max) is basically equivalent to the following

$rand_in_range_min_to_max = (int)($min + ($max - $min) * ($rand/mt_getrandmax()));

因此,不是从0到2 31 -1的理论范围中选择随机数,而是从$min$max选择数字。如果$min大于0$max小于1<<31-1,则仅此一项就会减少可能的种子值。

既然the presented attack是一种蛮力攻击,减少猜测次数也会减少完成暴力攻击的时间。

但是,由于蛮力过程的结果值不是实际的随机值,而只是随机值映射到的值,攻击者需要检查映射到该暴力的每个可能的输入值 - 强迫价值。该范围可以计算如下:

$rand_min = (int)(($rand_in_range_min_to_max - $min) / ($max - $min) * mt_getrandmax());
$rand_max = (int)($rand_min + mt_getrandmax() / ($max - $min + 1));

// range whose values are mapped onto $rand_in_range_min_to_max
$range = range($rand_min, $rand_max);
foreach ($range as $rand) {
    assert($rand_in_range_min_to_max === (int)($min + ($max - $min) * ($rand/mt_getrandmax())));
}

由于范围中的每个数字都被相同地映射,它们都只是用于按顺序生成下一个随机数的潜在数字。为了明确识别实际数字,攻击者最多需要mt_getrandmax() / ($max - $min)个随后生成的随机数。

所以,实际上,使用mt_rand($min, $max) 确实会增加攻击者查找实际种子的工作量,因为他必须对多个随机值强制种子,他需要{{随后生成随机数以唯一地标识正确的种子。