downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

openssl_seal> <openssl_public_encrypt
[edit] Last updated: Fri, 25 May 2012

view this page in

openssl_random_pseudo_bytes

(PHP 5 >= 5.3.0)

openssl_random_pseudo_bytes疑似乱数のバイト文字列を生成する

説明

string openssl_random_pseudo_bytes ( int $length [, bool &$crypto_strong ] )

疑似乱数のバイト文字列を生成します。長さは length パラメータで指定します。

暗号学的に強いアルゴリズムを使って疑似乱数を生成したかどうかを知ることもできます。 オプションのパラメータ crypto_strong を使います。 これが FALSE になることはまずないでしょうが、 古いシステムなどではそうなることもあります。

パラメータ

length

希望するバイト長。正の整数でなければなりません。PHP は、 このパラメータを非 null の整数値にキャストして利用します。

crypto_strong

これを渡しておくと、使ったアルゴリズムが暗号学的に強いものであるかどうかを表す boolean 値が格納されます。「強い」とは、 GPG やパスワードなどに使っても安全であるという意味です。強い場合は TRUE、そうでない場合は FALSE となります。

返り値

成功した場合は指定したバイト長の string を返します。失敗した場合に FALSE を返します。

例1 openssl_random_pseudo_bytes() の例

<?php
for ($i = -1$i <= 4$i++) {
    
$bytes openssl_random_pseudo_bytes($i$cstrong);
    
$hex   bin2hex($bytes);

    echo 
"Lengths: Bytes: $i and Hex: " strlen($hex) . PHP_EOL;
    
var_dump($hex);
    
var_dump($cstrong);
    echo 
PHP_EOL;
}
?>

上の例の出力は、 たとえば以下のようになります。

Lengths: Bytes: -1 and Hex: 0
string(0) ""
NULL

Lengths: Bytes: 0 and Hex: 0
string(0) ""
NULL

Lengths: Bytes: 1 and Hex: 2
string(2) "42"
bool(true)

Lengths: Bytes: 2 and Hex: 4
string(4) "dc6e"
bool(true)

Lengths: Bytes: 3 and Hex: 6
string(6) "288591"
bool(true)

Lengths: Bytes: 4 and Hex: 8
string(8) "ab86d144"
bool(true)

参考

  • bin2hex() - 2進表現のデータを16進表現に変換する
  • crypt() - 文字列の一方向のハッシュ化を行う
  • mt_rand() - よりよい乱数値を生成する
  • uniqid() - 一意な ID を生成する


openssl_seal> <openssl_public_encrypt
[edit] Last updated: Fri, 25 May 2012
 
add a note add a note User Contributed Notes openssl_random_pseudo_bytes
Anonymous 06-May-2012 12:17
Another way to get random 32bit ints:
function myRand($max){
    do{
        $result = floor($max*(hexdec(bin2hex(openssl_random_pseudo_bytes(4)))/0xffffffff));
    }while($result == $max);
    return $result;
}
christophe dot weis at statec dot etat dot lu 09-Jun-2011 12:09
Another replacement for rand() using OpenSSL.

Note that a solution where the result is truncated using the modulo operator ( % ) is not cryptographically secure, as the generated numbers are not equally distributed, i.e. some numbers may occur more often than others.

A better solution than using the modulo operator is to drop the result if it is too large and generate a new one.

<?php
function crypto_rand_secure($min, $max) {
       
$range = $max - $min;
        if (
$range == 0) return $min; // not so random...
       
$log = log($range, 2);
       
$bytes = (int) ($log / 8) + 1; // length in bytes
       
$bits = (int) $log + 1; // length in bits
       
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
       
do {
           
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes, $s)));
           
$rnd = $rnd & $filter; // discard irrelevant bits
       
} while ($rnd >= $range);
        return
$min + $rnd;
}
?>
crrodriguez at opensuse dot org 19-Jan-2011 09:32
Remember to request at very least 8 bytes of entropy, ideally 32 or 64, to avoid possible theorical bruteforce attacks.
acatalept at gmail 11-Jan-2011 11:24
FYI, openssl_random_pseudo_bytes() can be incredibly slow under Windows, to the point of being unusable.  It frequently times out (>30 seconds execution time) on several Windows machines of mine.

Apparently, it's a known problem with OpenSSL (not PHP specifically).

See: http://www.google.com/search?q=openssl_random_pseudo_bytes+slow
gorgo 17-Mar-2010 02:47
a simple way to generate a random password is:
<?php
$password
= base64_encode(openssl_random_pseudo_bytes($length, $strong));
?>

this function generates a password with a fallback to mt_rand() if no openssl is available:
<?php
/**
 * generates a random password, uses base64: 0-9a-zA-Z/+
 * @param int [optional] $length length of password, default 24 (144 Bit)
 * @return string password
 */
function generatePassword($length = 24) {
        if(
function_exists('openssl_random_pseudo_bytes')) {
           
$password = base64_encode(openssl_random_pseudo_bytes($length, $strong));
            if(
$strong == TRUE)
                return
substr($password, 0, $length); //base64 is about 33% longer, so we need to truncate the result
       
}
       
       
//fallback to mt_rand if php < 5.3 or no openssl available
       
$characters = '0123456789';
       
$characters .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/+';
       
$charactersLength = strlen($characters)-1;
       
$password = '';

       
//select some random characters
       
for ($i = 0; $i < $length; $i++) {
           
$password .= $characters[mt_rand(0, $charactersLength)];
        }       
       
        return
$password;
}
?>

note: openssl_random_pseudo_bytes() is considerably slower than mt_rand.
Tyler Larson 21-Aug-2009 03:18
Here's a drop-in replacement for rand() using OpenSSL as your PRNG:

<?php
   
function crypto_rand($min,$max) {
       
$range = $max - $min;
        if (
$range == 0) return $min; // not so random...
       
$length = (int) (log($range,2) / 8) + 1;
        return
$min + (hexdec(bin2hex(openssl_random_pseudo_bytes($length,$s))) % $range);
    }
?>
Tyler Larson 21-Aug-2009 02:29
If you don't have this function but you do have OpenSSL installed, you can always fake it:

<?php
   
function openssl_random_pseudo_bytes($length) {
       
$length_n = (int) $length; // shell injection is no fun
       
$handle = popen("/usr/bin/openssl rand $length_n", "r");
       
$data = stream_get_contents($handle);
       
pclose($handle);
        return
$data;
    }
?>

 
show source | credits | sitemap | contact | advertising | mirror sites