Movatterモバイル変換


[0]ホーム

URL:


PHP 8.5.0 Alpha 2 available for testing
    openssl_seal »
    « openssl_public_encrypt

    openssl_random_pseudo_bytes

    (PHP 5 >= 5.3.0, PHP 7, PHP 8)

    openssl_random_pseudo_bytesGenerate a pseudo-random string of bytes

    Description

    openssl_random_pseudo_bytes(int$length,bool&$strong_result =null):string

    Generates astring of pseudo-random bytes, with the number of bytes determined by thelength parameter.

    It also indicates if a cryptographically strong algorithm was used to produce the pseudo-random bytes, and does this via the optionalstrong_result parameter. It's rare for this to befalse, but some systems may be broken or old.

    Parameters

    length

    The length of the desired string of bytes. Must be a positive integer less than or equal to2147483647. PHP will try to cast this parameter to a non-null integer to use it.

    strong_result

    If passed into the function, this will hold abool value that determines if the algorithm used was "cryptographically strong", e.g., safe for usage with GPG, passwords, etc.true if it did, otherwisefalse

    Return Values

    Returns the generatedstring of bytes.

    Errors/Exceptions

    openssl_random_pseudo_bytes() throws anException on failure.

    Changelog

    VersionDescription
    8.0.0strong_result is nullable now.
    7.4.0 The function no longer returnsfalse on failure, but throws anException instead.

    Examples

    Example #1openssl_random_pseudo_bytes() example

    <?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;
    }
    ?>

    The above example will outputsomething similar to:

    Lengths: Bytes: 1 and Hex: 2string(2) "42"bool(true)Lengths: Bytes: 2 and Hex: 4string(4) "dc6e"bool(true)Lengths: Bytes: 3 and Hex: 6string(6) "288591"bool(true)Lengths: Bytes: 4 and Hex: 8string(8) "ab86d144"bool(true)

    See Also

    • random_bytes() - Get cryptographically secure random bytes
    • bin2hex() - Convert binary data into hexadecimal representation
    • crypt() - One-way string hashing
    • random_int() - Get a cryptographically secure, uniformly selected integer

    Found A Problem?

    Learn How To Improve This PageSubmit a Pull RequestReport a Bug
    add a note

    User Contributed Notes8 notes

    nahun@telemako
    11 years ago
    Here's an example to show the distribution of random numbers as an image. Credit to Hayley Watson at the mt_rand page for the original comparison between rand and mt_rand.

    rand is red, mt_rand is green and openssl_random_pseudo_bytes is blue.

    NOTE: This is only a basic representation of the distribution of the data. Has nothing to do with the strength of the algorithms or their reliability.

    <?php
    header
    ("Content-type: image/png");
    $sizex=800;
    $sizey=800;

    $img=imagecreatetruecolor(3*$sizex,$sizey);
    $r=imagecolorallocate($img,255,0,0);
    $g=imagecolorallocate($img,0,255,0);
    $b=imagecolorallocate($img,0,0,255);
    imagefilledrectangle($img,0,0,3*$sizex,$sizey,imagecolorallocate($img,255,255,255));

    $p=0;
    for(
    $i=0;$i<100000;$i++) {
    $np=rand(0,$sizex);
    imagesetpixel($img,$p,$np,$r);
    $p=$np;
    }

    $p=0;
    for(
    $i=0;$i<100000;$i++) {
    $np=mt_rand(0,$sizex);
    imagesetpixel($img,$p+$sizex,$np,$g);
    $p=$np;
    }

    $p=0;
    for(
    $i=0;$i<100000;$i++) {
    $np=floor($sizex*(hexdec(bin2hex(openssl_random_pseudo_bytes(4)))/0xffffffff));
    imagesetpixel($img,$p+ (2*$sizex),$np,$b);
    $p=$np;
    }

    imagepng($img);
    imagedestroy($img);
    ?>
    powtac at gmx dot de
    9 years ago
    [Editor's note: the bug has been fixed as of PHP 5.4.44, 5.5.28 and PHP 5.6.12]

    Until PHP 5.6 openssl_random_pseudo_bytes() did NOT use a "cryptographically strong algorithm"!
    See bug reporthttps://bugs.php.net/bug.php?id=70014 and the corresponding source code athttps://github.com/php/php-src/blob/php-5.6.10/ext/openssl/openssl.c#L5408
    christophe dot weis at statec dot etat dot lu
    14 years ago
    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
    functioncrypto_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;
    }
    ?>
    mailjeffclayton [at] gmail
    5 years ago
    Getting an integer value from a given range with an even distribution:

    This function I created to solve the problem of modulo results causing overlap of ranged results (which gave an uneven distribution).

    What I mean for those not as familiar with the problem:

    Using bytes for base 256 (base 16) and attempting to find a value in a range of values that may be for example 10-20 (a spread of 11) will not divide evenly, so values (using mod) will overlap and give more priority to some numbers than others.

    Instead of calculating based on byte values, I used the byte values as keys to sort. This is very fast, and does not require large multiplications of data space that easily go over the value of Max Int.

    Additionally: To make the user-supplied arguments not care about order I am using a handy swap function I found in the wild in conjunction with my function below.

    // swap function

    function swap(&$a,&$b) { list($a,$b)=array($b,$a); } // swap 2 variables-- no temp variable needed!

    // function to get a random value within a given range of integers

    function get_secure_random_ranged_value($max=99, $min=0) // handles 1 or 2 arguments, order does not matter
    {
    $sortarray = array();
    $lo = (int)$min;
    $hi = (int)$max;
    if ($lo > $hi) swap($lo,$hi);
    $data_range = abs($hi - $lo) + 1; // +1 includes both the lowest 'zero' value and highest value of range
    $bytes_per_key = 4; // Max: ffff hex = 4,294,967,296 dec (over 4 billion) -- large span of random values covers massive datasets
    $num_bytes = $data_range * $bytes_per_key;
    $byte_string = (bin2hex(openssl_random_pseudo_bytes($num_bytes))); // only one call needed to get string of bytes
    $byte_blocksize = $bytes_per_key << 1; // shift multiply by 2 since a byte is 2 characters wide

    while ($key = substr($byte_string,0,$byte_blocksize)) { // get next byte block from string
    $byte_string = substr($byte_string,$byte_blocksize); // remove selected byte block from string
    $sortarray[]=$key; // populate the array with keys temporarily as array values
    }

    $sortarray = array_flip($sortarray); // swap to use the byte values as keys
    ksort($sortarray); // randomize by keys
    return array_shift($sortarray) + $lo; // grab top value from array and add it to the lowest value in the range
    }

    //
    // example getting values from 0 to 21:
    //

    for ($i=1;$i<=10;$i++) { $rnd = get_secure_random_ranged_value(21); echo "-> result: ".($rnd)." <br />\n"; }

    //
    // example getting values from 14 to 21:
    //

    for ($i=1;$i<=10;$i++) { $rnd = get_secure_random_ranged_value(14,21); echo "-> result: ".($rnd)." <br />\n"; }

    //
    // sample results from 14-21
    //

    -> result: 14
    -> result: 18
    -> result: 20
    -> result: 15
    -> result: 20
    -> result: 16
    -> result: 21
    -> result: 15
    -> result: 16
    -> result: 17
    acatalept at gmail
    14 years ago
    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
    Tyler Larson
    15 years ago
    If you don't have this function but you do have OpenSSL installed, you can always fake it:

    <?php
    functionopenssl_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;
    }
    ?>
    crrodriguez at opensuse dot org
    14 years ago
    Remember to request at very least 8 bytes of entropy, ideally 32 or 64, to avoid possible theorical bruteforce attacks.
    umairkhi at hotmail dot com
    7 years ago
    After the fix of insecure number generation here:

    http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-8867

    This function as well as the text here needs an update. I believe this function is safe to use in FIPS compliant apps as well as it now used RAND_bytes instead of the insecure RAND_pseudo_bytes().
    add a note
    To Top
    and to navigate •Enter to select •Esc to close
    PressEnter without selection to search using Google

    [8]ページ先頭

    ©2009-2025 Movatter.jp