- Notifications
You must be signed in to change notification settings - Fork146
PHP 5.x support for random_bytes() and random_int()
License
paragonie/random_compat
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
PHP 5.x polyfill forrandom_bytes() andrandom_int() created and maintainedbyParagon Initiative Enterprises.
Although this libraryshould function in earlier versions of PHP, we will onlyconsider issues relevant tosupported PHP versions.If you are using an unsupported version of PHP, please upgrade as soon as possible.
Although this library has been examined by some security experts in the PHPcommunity, there will always be a chance that we overlooked something. Pleaseask your favorite trusted hackers to hammer it for implementation errors andbugs before even thinking about deploying it in production.
Do not use the master branch, use astable release.
For the background of this library, please refer to our blog post onGenerating Random Integers and Strings in PHP.
If PHP cannot safely generate random data, this library will throw anException.It will never fall back to insecure random data. If this keeps happening, upgradeto a newer version of PHP immediately.
WithComposer:
# For libraries and frameworks that support PHP 5 but may be used by# other software that only supports PHP 7:composer require paragonie/random_compat:\>=2# For software that explicitly needs PHP 5 support:composer require paragonie/random_compat:\<9.99Signed PHP Archive:
As of version 1.2.0, we also ship an ECDSA-signed PHP Archive with each stablerelease on Github.
- Downloadthe
.phar,.phar.pubkey, and.phar.pubkey.ascfiles. - (Recommended but not required) Verify the PGP signature of
.phar.pubkey(contained within the.ascfile) using thePGP public key for Paragon Initiative Enterprises. - Extract both
.pharand.phar.pubkeyfiles to the same directory. require_once "/path/to/random_compat.phar";- When a new version is released, you only need to replace the
.pharfile;the.pubkeywill not change (unless our signing key is ever compromised).
Manual Installation:
- Downloada stable release.
- Extract the files into your project.
require_once "/path/to/random_compat/lib/random.php";
The entrypoint should belib/random.php directly, not any of the other files in/lib.
This library exposes theCSPRNG functions added in PHP 7for use in PHP 5 projects. Their behavior should be identical.
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"
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)
When handling exceptions and errors you must account for differences betweenPHP 5 and PHP7.
The differences:
- Catching
Errorworks, so long as it is caught beforeException. - Catching
Exceptionhas different behavior, without previously catchingError. - There isno portable way to catch all errors/exceptions.
Always catchError beforeException.
try {returnrandom_int(1,$userInput);}catch (TypeError$e) {// This is okay, so long as `Error` is caught before `Exception`.thrownewException('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.thrownewInternalServerErrorException('Oops, our server is bust and cannot generate any random data.',500,$e );}
If an Exception is thrown, then your operating system is not secure.
- If you're on Windows, make sure you enable mcrypt.
- If you're on any other OS, make sure
/dev/urandomis readable.- FreeBSD jails need to expose
/dev/urandomfrom the host OS - If you use
open_basedir, make sure/dev/urandomis allowed
- FreeBSD jails need to expose
This library does not (and will not accept any patches to) fall back toan insecure random number generator.
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 explicitlyrequires random_compat 2, such asthis secure PHP encryption library),you will get a version conflict.
The solution is to get the project to update its requirement string to allowversion 2 and above to be used instead of hard-locking users to version 1.
"require" { ...- "paragonie/random_compat": "~1.1",+ "paragonie/random_compat": ">=1", ...}Note: There is a special version called9.99.99 which makes thislibrary do nothing, but is only installable on PHP 7.
If you're writing software (e.g. a library) that supports PHP 5, but maybe used by software that doesn't, you'll want to allow9.99.99 to beinstalled. The above diff is what you want.
Conversely, if you're writing software that (in and of itself) supportsPHP 5, you do not want 9.99.99 to be installed, so you'll want to makethis change instead:
"require" { ...- "paragonie/random_compat": "~1.1",+ "paragonie/random_compat": ">=1 <9.99", ...}To avoid installing "empty" version9.99.99 you can addreplace sectionin your rootcomposer.json:
"replace": { "paragonie/random_compat": "9.99.99"},If you're using the PHP Archive (Phar) approach rather than Composer, andyou are getting an error message to the effect of "manifest read lengthwas{int1} should be{int2}", the Phar extension may not be enabled.
Seethis commentfor specific guidance on how to fix this issue.
This project would not be anywhere near as excellent as it is today if itweren't for the contributions of the following individuals:
- @AndrewCarterUK (Andrew Carter)
- @asgrim (James Titcumb)
- @bcremer (Benjamin Cremer)
- @chriscct7 (Chris Christoff)
- @CodesInChaos (Christian Winnerlein)
- @ConnorVG (Connor S. Parks)
- @cs278 (Chris Smith)
- @cweagans (Cameron Eagans)
- @dd32 (Dion Hulse)
- @geggleto (Glenn Eggleton)
- @glensc (Elan Ruusamäe)
- @GrahamCampbell (Graham Campbell)
- @ircmaxell (Anthony Ferrara)
- @jdevalk (Joost de Valk)
- @jedisct1 (Frank Denis)
- @juliangut (Julián Gutiérrez)
- @kelunik (Niklas Keller)
- @lt (Leigh)
- @MasonM (Mason Malone)
- @menkaff (Mehran NikNafs)
- @mmeyer2k (Michael M)
- @narfbg (Andrey Andreev)
- @nicolas-grekas (Nicolas Grekas)
- @ocean90 (Dominik Schilling)
- @oittaa
- @oucil (Kevin Farley)
- @philios33 (Phil Nicholls)
- @redragonx (Stephen Chavez)
- @relaxnow (Boy Baukema)
- @rchouinard (Ryan Chouinard)
- @rugk
- @SammyK (Sammy Kaye Powers)
- @scottchiefbaker (Scott Baker)
- @skyosev (Stoyan Kyosev)
- @sthen (Stuart Henderseon)
- @stof (Christophe Coevoet)
- @teohhanhui (Teoh Han Hui)
- @tom-- (Tom Worster)
- @tsyr2ko
- @trowski (Aaron Piotrowski)
- @twistor (Chris Lepannen)
- @vinkla (Vincent Klaiber)
- @voku (Lars Moelleken)
- @xabbuh (Christian Flothmann)
If your company uses this library in their products or services, you may beinterested inpurchasing a support contract from Paragon Initiative Enterprises.
About
PHP 5.x support for random_bytes() and random_int()
Topics
Resources
License
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
