32

I need to generate a single-use token in PHP. There are two functions available that I can use for this that seem to do the same thing: random_bytes and openssl_random_pseudo_bytes. For example, using random_bytes:

var_dump(bin2hex(random_bytes(12)));

--> string(24) "338f489ec37a2c2b4943905d"

and using openssl_random_pseudo_bytes:

var_dump(bin2hex(openssl_random_pseudo_bytes(12)));

--> string(24) "1c7febea20029bd524fba8e7"

openssl_random_pseudo_bytes is PHP 5.3 and up (so I assume it's been around longer), and random_bytes is PHP 7. I'm using PHP 7 so I can use either.

So is there any major (or minor for that matter) difference between the two? If not, I'm tempted to go with random_bytes simply because it has an easier name ( = code that's easier to read).

Dave Hollingworth
  • 3,670
  • 6
  • 29
  • 43
  • There are no real differences. – Charlotte Dunois Aug 02 '16 at 09:30
  • I do not advice you to use openssl anymore .. many security advisors report me to stop using openSSL – Mohammad Alabed Aug 02 '16 at 09:41
  • 2
    As far as I know, how the bytes is generated by `random_bytes` is platform dependent but the other one will need openssl extension available. – frz3993 Aug 02 '16 at 09:42
  • Here's the [`random_bytes` RFC](https://wiki.php.net/rfc/easy_userland_csprng) for what it's worth. It doesn't say much about `openssl_random_pseudo_bytes()` though. Although there was a PHP [security bug](https://bugs.php.net/bug.php?id=70014) last year that affected 5.6. This might not be relevant if you are using PHP7. – Darragh Enright Aug 02 '16 at 09:48
  • Some interesting information about `openssl_random_pseudo_bytes` here: https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php – Darragh Enright Aug 02 '16 at 09:53
  • @deceze `random_bytes — Generates cryptographically secure pseudo-random bytes` Hmm... – Charlotte Dunois Aug 02 '16 at 10:08
  • @Charlotte The joke is that *`openssl_random_pseudo_bytes`* is the insecure one… – deceze Aug 02 '16 at 10:09
  • Let's look at the problem: **I need to generate a single-use token in PHP**. How can you determine that tokens generated before haven't been used? By storing them to db and then comparing - that takes space and time. The best approach is using one of the algorithms designed for that specific purpose (rfc4226, rfc6238) or simply use an incrementing number that you encrypt and deliver encrypted value. Once the token arrives, decrypt it, read the number, check if it's greater than what you have stored - if yes, token is valid, otherwise a replay is detected, if decryption fails - invalid token. – Mjh Aug 02 '16 at 10:09
  • @deceze Oh well, I thought since it's from OpenSSL it should be secure. Never used it nor read the manual page. Looks like OpenSSL should be sorted out :D – Charlotte Dunois Aug 02 '16 at 10:10
  • @Mjh That's one very specific scenario for using random numbers… but there are a ton more scenarios which are not solved by this method. Not sure what your point is here...? – deceze Aug 02 '16 at 10:16
  • @deceze my point is that I provided an alternative solution for the actual problem. It has nothing to do with random numbers. – Mjh Aug 02 '16 at 10:17

3 Answers3

38

openssl_random_pseudo_bytes is part of the OpenSSL extension, which must be explicitly configured and included in the PHP compilation process and requires external dependencies.

random_bytes is new in PHP 7 as the native always-available PHP method to generate random bytes, which chooses its internal source of randomness depending on the platform it's on.

The main reason for introducing random_bytes was that generating pseudo-random data was always a bit of a headache in PHP, requiring developers to be platform-aware and possibly using several different fallback methods depending on which extensions or system-level functions are available. This often led to bugs in individual implementations, which is particularly concerning in security-relevant code. random_bytes simplifies this by providing one function which is always available and uses the best possible source of randomness available. If you can target PHP 7+ exclusively, it should be your go-to method.

deceze
  • 510,633
  • 85
  • 743
  • 889
5

Just to update, the cryptographic insecurity in openssl_random_pseudo_bytes was fixed in 2016. More details here:

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

It usese RAND_bytes now, which OpenSSL recommends in its wiki:

https://wiki.openssl.org/index.php/Random_Numbers#FIPS_Mode

Umair Durrani
  • 79
  • 1
  • 3
2

According to php manual

random_bytes : Generates cryptographically secure pseudo-random bytes openssl_random_pseudo_bytes : Generate a pseudo-random string of bytes

so main difference is the cryptographically secure

The openssl_random_pseudo_bytes() PHP function calls the RAND_psuedo_bytes() OpenSSL function, which the OpenSSL docs say should only be used for non-cryptographic purposes:

https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php

Mohammad Alabed
  • 809
  • 6
  • 17
  • 2
    The `crypto_strong` output parameter indicates whether the openssl method returned a cryptographically secure string or not (depending on platform). – SilverlightFox Aug 02 '16 at 10:27
  • you are right .. but i am still do not suggest it for security issues which is reported in latest php conference at Istanbul PHPKonf http://phpkonf.org/ (Alexander Makarov) – Mohammad Alabed Aug 02 '16 at 11:50