Take the State of PHP 2026 Survey →

Reliable User-land CSPRNG View as Markdown

Implemented (PHP 7.0)
Authors
Sammy Kaye Powers me@sammyk.me & Leigh leigh@php.net
Date
2015-02-20
Version
0.5
Source
wiki.php.net/rfc/easy_userland_csprng

Vote

Reliable user-land CSPRNG closed
Yes
41
No
0
41 voters
aharvey Yes 2015-03-17 00:14
auroraeosrose Yes 2015-03-16 12:46
bishop Yes 2015-03-15 17:58
crodas Yes 2015-03-15 04:41
damz Yes 2015-03-16 00:13
derick Yes 2015-03-15 23:02
dragoonis Yes 2015-03-27 20:41
eliw Yes 2015-03-18 13:05
galvao Yes 2015-03-28 03:04
gasolwu Yes 2015-03-16 17:26
hywan Yes 2015-03-15 07:09
ircmaxell Yes 2015-03-14 22:39
jedibc Yes 2015-03-16 09:33
jmikola Yes 2015-03-16 01:06
jpauli Yes 2015-03-16 08:52
jwage Yes 2015-03-15 23:41
kinncj Yes 2015-03-15 13:24
klaussilveira Yes 2015-03-26 20:35
lcobucci Yes 2015-03-15 14:21
leigh Yes 2015-03-15 03:34
leszek Yes 2015-03-16 09:28
lstrojny Yes 2015-03-27 18:47
mbeccati Yes 2015-03-16 08:31
mike Yes 2015-03-28 12:44
nikic Yes 2015-03-19 08:15
omars Yes 2015-03-18 12:11
pajoye Yes 2015-03-15 03:30
pauloelr Yes 2015-03-15 16:52
ralphschindler Yes 2015-03-23 21:59
ramsey Yes 2015-03-23 21:57
rdlowrey Yes 2015-03-15 05:06
rdohms Yes 2015-03-21 09:52
rmf Yes 2015-03-18 00:27
salathe Yes 2015-03-16 09:10
stas Yes 2015-03-15 22:22
stelianm Yes 2015-03-17 19:53
svpernova09 Yes 2015-03-16 14:06
thekid Yes 2015-03-15 10:25
weierophinney Yes 2015-03-17 19:19
yohgaki Yes 2015-03-15 02:21
zeev Yes 2015-03-15 23:58

Discussions on the mailing list

[RFC] [DISCUSSION] Reliable user-land CSPRNG
by Sammy Kaye Powers · 19 messages
[RFC] [VOTE] Vote open for reliable user-land CSPRNG
by Sammy Kaye Powers · 11 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:51 UTC

Introduction

This RFC proposes adding a user-land API for an easy to use and reliable CSPRNG in PHP.

The Problem

By default PHP does not provide an easy mechanism for accessing cryptographically strong random numbers in user-land. Users have a few options like openssl_random_pseudo_bytes(), mcrypt_create_iv() or directly opening /dev/*random devices to obtain high quality pseudo-random bytes, but unfortunately system support for these functions and extensions varies between platforms and each come with their own set of problems

  • The mcrypt_create_iv() function has no dependency on MCrypt lib yet it requires the MCrypt extension to be installed before it can be used. Users are forced to include an entire library for no reason.
  • openssl_random_pseudo_bytes() is provided by the OpenSSL lib. This function comes with a $crypto_strong the meaning of which may just confuse users.
  • Falling back to /dev/urandom is OS-specific.

In addition users may attempt to generate their own streams of random bytes relying on rand() or mt_rand(), and this is something we absolutely want to avoid.

Proposal

There should be a user-land API to easily return an arbitrary length of cryptographically secure pseudo-random bytes directly and work on any supported platform.

The initial proposal is to add two user-land functions that return the bytes as binary and integer. Arbitrary length strings of random bytes are important for salts, keys and initialisation vectors. Integers based on CS random are important for applications where unbiased results are critical (i.e. shuffling a Poker deck).

Signatures:

random_bytes(int length);
random_int(int min, int max);

Examples:

$randomStr = random_bytes($length = 16);
 
$randomInt = random_int($min = 0, $max = 127);

The sources of random used are as follows:

  • On windows CryptGenRandom is used exclusively
  • arc4random_buf() is used if it is available (generally BSD specific)
  • /dev/arandom is used where available
  • /dev/urandom is used where none of the above is available
  • An error is thrown in the event that a sufficient source of randomness is unavailable.

Backward Incompatible Changes

Any user-land code that defines a random_bytes() or random_int() function would generate a fatal error, however it is likely that these functions provide the same or similar functionality as desired.

Proposed PHP Version(s)

PHP 7

RFC Impact

To SAPIs

This RFC should not impact the SAPI's.

To Existing Extensions

No existing extensions are affected.

To Opcache

Opcache is unaffected.

New Constants

There would be no new constants.

php.ini Defaults

There would be no new php.ini defaults.

Open Issues

  • Nothing yet

Unaffected PHP Functionality

This change does not affect any of the existing rand() or mt_rand() functionality.

Future Scope

The concepts from the RFC could be used to:

  • Deprecate mcrypt_create_iv()
  • Improve session_id randomness generation
  • Detect LibreSSL-portable for arc4random() on Linux

Patches and Tests

The current patch can be found here: https://github.com/php/php-src/pull/1119

Proposed Voting Choices

The voting choices are yes (in favor for accepting this RFC for PHP 7) or no (against it).

Vote

Vote starts on March 14th, and will end two weeks later, on March 28th.

This RFC requires a 2/3 majority.

Vote: Reliable user-land CSPRNG — Yes: 41 · No: 0 (closed)

Changelog

  • 0.5: Updated the function header for random_int() to reflect all args as required. - SammyK
  • 0.4: Added BC info. Updated patch link to point to PR. - SammyK
  • 0.3: Changed -PHP_INT_MAX to ~PHP_INT_MAX (thanks @trevorsuarez) - SammyK
  • 0.2: Condensed the problem domain into something more focused. Added function sigs. - Leigh.
  • 0.1: Mmmm drafty - Leigh
  • 0.0: Initial draft - need Leigh's input - SammyK

Acknowledgements

Big thanks to Anthony Ferrara, Daniel Lowrey, E. Smith and all the kids in the PHP room for all the help with this one!