Edited at

PHP7調査(31)暗号論的に安全な疑似乱数生成器(CSRPNG)を提供する新関数

More than 3 years have passed since last update.

PHP5までは暗号論的に安全な疑似乱数生成器(CSPRNG)を提供する標準関数がなかったため、CSPRNGが必要な場合に自分で明示的に/dev/urandomにアクセスしたりしていました。opensslエクステンションおよびmcryptエクステンションもCSPRNG関数を提供していますが1、どちらも必須のエクステンションでは無いため、ライブラリなどでは採用しにくい状況があったはずです。

PHP7から、どの環境でも動くCSPRNG関数としてrandom_bytes()random_int()の2つが新規実装されます。

<?php

// ランダムな2バイトの文字列を返す。各バイトは0x00から0xffのどれか。
var_dump(bin2hex(random_bytes(2)));

// 5以上9以下の整数をランダムに返す
var_dump(random_int(5,9));


実装


  • WindowsではCryptGenRandom()が使われます。


  • arc4random_buf()があればそれを使います(通常はBSDのみ)。


  • /dev/arandomがあればそれを使います。

  • 上のどれも無ければ/dev/urandomを使います。

  • これらの乱数生成源が一つも見つからなければエラーになります。


暗号論的に安全な疑似乱数とは

「暗号論的に安全な疑似乱数」というのはお決まりの言い方で、暗号の実装中で利用しても暗号の安全性を崩さないような、予測不可能性が保証されている乱数のことです。

ちなみに、統計的なランダムさが必要な場合はmt_rand()でも全く問題ありません。通常の疑似乱数列に比べて暗号論的に安全な疑似乱数列の方が乱数の生成コストが高い傾向があるので、例えばモンテカルロシミュレーションを行うような場合はmt_rand()の方がふさわしいと言えるでしょう。ゲームのサイコロや何かの抽選などの場合は微妙っちゃ微妙ですが、好きな方を使えばいいのではないでしょうか。


参照





  1. openssl_random_pseudo_bytes()およびmcrypt_create_iv()