0

私はそれらの記事に出くわしました:

関数のシードを回復する方法を示しmt_rand()ます。添付されたコードは、最初の mt_rand() から 1 分 (またはそれ以上) でブルート フォース シードを実行できます。実際のところ、ほとんどの PHP アプリケーションは範囲引数を指定して mt_rand を使用しています。これにより、結果が切り捨てられます。私の質問は、クラックがより困難になるかどうかです。まず、たった1つの数字で力ずくで攻撃することはできないと想像できます。彼はシーケンス全体を持っている必要があります。クラッキングプロセスが大幅に長くなりますか、それとも問題ではありませんか? mt_rand(from, to)よりもはるかに安全ですmt_rand()か?

4

1 に答える 1

2

呼び出しmt_rand($min, $max)は、基本的に次と同等です

$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これだけで可能なシード値の量がすでに減少しています。

提示された攻撃はブルート フォース攻撃であるため、推測の数を減らすと、ブルート フォース プロセスを完了するまでの時間も短縮されます。

ただし、ブルート フォース プロセスの結果の値は実際のランダム値ではなく、ランダム値がマッピングされた値にすぎないため、攻撃者はそのブルート フォース値にマッピングされた可能性のある入力値をそれぞれチェックする必要があります。その範囲は次のように計算できます。

$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) 増加します。攻撃者は、複数の乱数値に対してブルート フォース シードを実行する必要がありmt_getrandmax() / ($max - $min)、その後、正しいシードを一意に識別するために乱数を生成する必要があるからです。

于 2013-04-28T11:21:45.553 に答える