rfc:easy_userland_csprng

This is an old revision of the document!


PHP RFC: Easy User-land CSPRNG

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 and each come with their own set of problems

  • mcrypt_create_iv() has no dependency on MCrypt lib. 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 and can fail when open_basedir is set.

See the Facebook PHP SDK's implementation of a CSPRNG in PHP to understand how much code is needed in user-land to simply generate cryptographically secure pseudo-random bytes.

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 server configuration or OS.

The initial proposal is to add two user-land functions that return the bytes as binary and integer.

Signatures:

random_bytes(int length);
random_int([int min = ~PHP_INT_MAX [, int max = PHP_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 present for fd-less random
  • /dev/arandom is used where available
  • /dev/urandom is used where none of the above is available

Backward Incompatible Changes

There would be no BC breaks.

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
  • Improve fd-less random for chroot environments with our own arc4random and the linux getrandom syscall
  • Add complimentary easy-use and secure by default cryptography functions

Patches and Tests

References

None so far.

Rejected Features

None so far.

Changelog

  • 0.3: Changed -PHP_INT_MAX to ~PHP_INT_MAX (thanks @trevorsuarez)
  • 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

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!

rfc/easy_userland_csprng.1424811917.txt.gz · Last modified: 2017/09/22 13:28 (external edit)