PHP Classes

random_compat: Provide random_bytes and random_int functions

Recommend this page to a friend!
  Info   Documentation   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
Not enough user ratingsTotal: 67 All time: 10,346 This week: 571Up
Version License PHP version Categories
random_compat 1.0MIT/X Consortium ...5PHP 5, Cryptography, Security
Description 

Author

This package can provide random_bytes and random_int functions that work in versions before PHP 7.

It can generate a string of random characters and random integers as an alternative that works as a polyfill that works well regardless if PHP is working before PHP 7 or not.

Innovation Award
PHP Programming Innovation award nominee
March 2018
Number 3
PHP 7 introduced a new set of functions that can generate random data that is more suitable for security purposes.

This package provide replacement functions for random_bytes and random_int that also works under PHP 5 as well.

Manuel Lemos
Picture of Scott Arciszewski
  Performance   Level  
Name: Scott Arciszewski <contact>
Classes: 37 packages by
Country: United States United States
Age: ???
All time rank: 1173170 in United States United States
Week rank: 28 Up5 in United States United States Up
Innovation award
Innovation award
Nominee: 28x

Winner: 1x

Documentation

random_compat

Build Status Scrutinizer Latest Stable Version Latest Unstable Version License Downloads

PHP 5.x polyfill for random_bytes() and random_int() created and maintained by Paragon Initiative Enterprises.

Although this library should function in earlier versions of PHP, we will only consider issues relevant to supported PHP versions. If you are using an unsupported version of PHP, please upgrade as soon as possible.

Important

Although this library has been examined by some security experts in the PHP community, there will always be a chance that we overlooked something. Please ask your favorite trusted hackers to hammer it for implementation errors and bugs before even thinking about deploying it in production.

Do not use the master branch, use a stable release.

For the background of this library, please refer to our blog post on Generating Random Integers and Strings in PHP.

Usability Notice

If PHP cannot safely generate random data, this library will throw an Exception. It will never fall back to insecure random data. If this keeps happening, upgrade to a newer version of PHP immediately.

Installing

With Composer:

composer require paragonie/random_compat

Signed PHP Archive:

As of version 1.2.0, we also ship an ECDSA-signed PHP Archive with each stable release on Github.

  1. Download the .phar, .phar.pubkey, and .phar.pubkey.asc files.
  2. (Recommended but not required) Verify the PGP signature of `.phar.pubkey` (contained within the `.asc` file) using the PGP public key for Paragon Initiative Enterprises.
  3. Extract both `.phar` and `.phar.pubkey` files to the same directory.
  4. `require_once "/path/to/random_compat.phar";`
  5. When a new version is released, you only need to replace the `.phar` file; the `.pubkey` will not change (unless our signing key is ever compromised).

Manual Installation:

  1. Download a stable release.
  2. Extract the files into your project.
  3. `require_once "/path/to/random_compat/lib/random.php";`

The entrypoint should be lib/random.php directly, not any of the other files in /lib.

Usage

This library exposes the CSPRNG functions added in PHP 7 for use in PHP 5 projects. Their behavior should be identical.

Generate a string of random bytes

try {
    $string = random_bytes(32);
} catch (TypeError $e) {
    // Well, it's an integer, so this IS unexpected.
    die("An unexpected error has occurred"); 
} catch (Error $e) {
    // This is also unexpected because 32 is a reasonable integer.
    die("An unexpected error has occurred");
} catch (Exception $e) {
    // If you get this message, the CSPRNG failed hard.
    die("Could not generate a random string. Is our OS secure?");
}

var_dump(bin2hex($string));
// string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f"

Generate a random integer between two given integers (inclusive)

try {
    $int = random_int(0, 255);
} catch (TypeError $e) {
    // Well, it's an integer, so this IS unexpected.
    die("An unexpected error has occurred"); 
} catch (Error $e) {
    // This is also unexpected because 0 and 255 are both reasonable integers.
    die("An unexpected error has occurred");
} catch (Exception $e) {
    // If you get this message, the CSPRNG failed hard.
    die("Could not generate a random int. Is our OS secure?");
}

var_dump($int);
// int(47)

Exception handling

When handling exceptions and errors you must account for differences between PHP 5 and PHP7.

The differences:

  • Catching `Error` works, so long as it is caught before `Exception`.
  • Catching `Exception` has different behavior, without previously catching `Error`.
  • There is no portable way to catch all errors/exceptions.

Our recommendation

Always catch Error before Exception.

Example

try {
    return random_int(1, $userInput);
} catch (TypeError $e) {
    // This is okay, so long as `Error` is caught before `Exception`.
    throw new Exception('Please enter a number!');
} catch (Error $e) {
    // This is required, if you do not need to do anything just rethrow.
    throw $e;
} catch (Exception $e) {
    // This is optional and maybe omitted if you do not want to handle errors
    // during generation.
    throw new InternalServerErrorException(
        'Oops, our server is bust and cannot generate any random data.',
        500,
        $e
    );
}

Troubleshooting

Exception: "Could not gather sufficient random data"

If an Exception is thrown, then your operating system is not secure.

  1. If you're on Windows, make sure you enable mcrypt.
  2. If you're on any other OS, make sure `/dev/urandom` is readable. * FreeBSD jails need to expose `/dev/urandom` from the host OS * If you use `open_basedir`, make sure `/dev/urandom` is allowed

This library does not (and will not accept any patches to) fall back to an insecure random number generator.

Version Conflict with [Other PHP Project]

If you're using a project that has a line like this in its composer.json

"require" {
    ...
    "paragonie/random_compat": "~1.1",
    ...
}

...and then you try to add random_compat 2 (or another library that explicitly requires random_compat 2, such as this secure PHP encryption library), you will get a version conflict.

The solution is to get the project to update its requirement string to allow version 2 and above to be used instead of hard-locking users to version 1.

"require" {
    ...
-    "paragonie/random_compat": "~1.1",
+    "paragonie/random_compat": "^1|^2",
    ...
}

Contributors

This project would not be anywhere near as excellent as it is today if it weren't for the contributions of the following individuals:


  Files folder image Files (43)  
File Role Description
Files folder imagedist (2 files)
Files folder imagelib (10 files)
Files folder imageother (1 file, 1 directory)
Files folder imagetests (4 directories)
Accessible without login Plain text file .scrutinizer.yml Data Auxiliary data
Accessible without login Plain text file .travis.yml Data Auxiliary data
Accessible without login Plain text file build-phar.sh Data Auxiliary data
Accessible without login Plain text file CHANGELOG.md Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file phpunit.sh Data Auxiliary data
Accessible without login Plain text file phpunit.xml.dist Data Auxiliary data
Accessible without login Plain text file psalm-autoload.php Aux. Auxiliary script
Accessible without login Plain text file psalm.xml Data Auxiliary data
Accessible without login Plain text file RATIONALE.md Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation
Accessible without login Plain text file SECURITY.md Data Auxiliary data

  Files folder image Files (43)  /  dist  
File Role Description
  Accessible without login Plain text file random_compat.phar.pubkey Data Auxiliary data
  Accessible without login Plain text file random_compat.phar.pubkey.asc Data Auxiliary data

  Files folder image Files (43)  /  lib  
File Role Description
  Accessible without login Plain text file byte_safe_strings.php Example Example script
  Accessible without login Plain text file cast_to_int.php Example Example script
  Accessible without login Plain text file error_polyfill.php Class Class source
  Accessible without login Plain text file random.php Example Example script
  Accessible without login Plain text file random_bytes_com_dotnet.php Example Example script
  Accessible without login Plain text file random_bytes_dev_urandom.php Example Example script
  Accessible without login Plain text file random_bytes_libsodium.php Example Example script
  Accessible without login Plain text file random_bytes_libsodium_legacy.php Example Example script
  Accessible without login Plain text file random_bytes_mcrypt.php Example Example script
  Accessible without login Plain text file random_int.php Example Example script

  Files folder image Files (43)  /  other  
File Role Description
Files folder imageide_stubs (4 files)
  Accessible without login Plain text file build_phar.php Example Example script

  Files folder image Files (43)  /  other  /  ide_stubs  
File Role Description
  Accessible without login Plain text file COM.php Class Class source
  Accessible without login Plain text file com_exception.php Class Class source
  Accessible without login Plain text file libsodium.php Class Class source
  Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (43)  /  tests  
File Role Description
Files folder imagefull (2 files)
Files folder imagespecific (5 files)
Files folder imageunit (3 files)
Files folder imageunit_with_basedir (3 files)

  Files folder image Files (43)  /  tests  /  full  
File Role Description
  Accessible without login Plain text file DieHardTest.php Class Class source
  Accessible without login Plain text file StatTest.php Class Class source

  Files folder image Files (43)  /  tests  /  specific  
File Role Description
  Accessible without login Plain text file capicom.php Aux. Auxiliary script
  Accessible without login Plain text file dev_urandom.php Aux. Auxiliary script
  Accessible without login Plain text file libsodium.php Aux. Auxiliary script
  Accessible without login Plain text file libsodium_legacy.php Aux. Auxiliary script
  Accessible without login Plain text file mcrypt.php Aux. Auxiliary script

  Files folder image Files (43)  /  tests  /  unit  
File Role Description
  Accessible without login Plain text file RandomBytesTest.php Class Class source
  Accessible without login Plain text file RandomIntTest.php Class Class source
  Accessible without login Plain text file UtilityTest.php Class Class source

  Files folder image Files (43)  /  tests  /  unit_with_basedir  
File Role Description
  Accessible without login Plain text file RandomBytesTest.php Class Class source
  Accessible without login Plain text file RandomIntTest.php Class Class source
  Accessible without login Plain text file UtilityTest.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads Download Rankings  
 100%
Total:67
This week:0
All time:10,346
This week:571Up