15

I know PHP's mt_rand() should not be used for security purposes as its results are not cryptographically strong. Yet a lot of PHP code does just that, or uses it as a fallback if better sources of randomness are not available.

So how bad is it? What sources of randomness does mt_rand use for seeding? And are there other security problems with mt_rand for cryptographic applications?

Jon
  • 428,835
  • 81
  • 738
  • 806
JanKanis
  • 6,346
  • 5
  • 38
  • 42

1 Answers1

19

In PHP 5.4, if mt_rand is automatically seeded the first time it's used (PHP source). The seed value is a function of the current timestamp, the PHP process PID and a value produced by PHP's internal LCG. I didn't check the source for previous versions of PHP, but the documentation implies that this seeding algorithm has been in use starting from PHP 5.2.1.

The RNG algorithm behind mt_rand is the Mersenne Twister. It doesn't really make sense to talk about "how bad" it is, because it's clearly documented (not on the PHP docs page, unfortunately) that it is entirely unsuitable for cryptographic applications. If you want crypto-strength randomness, use a documented crypto-strength generator.

Update: You might also want to look at this question from crypto.SE.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • You might find it interesting to know that `/dev/random/` in FreeBSD, OpenBSD and OSX is filled by the Fortuna algorithm, which **is** cryptographically secure. – Leigh Jul 06 '12 at 09:15
  • Following the PHP sources, it appears PHP's internal LCG is also seeded with the time and pid, so it doesn't add a lot of randomness. That link to crypto.stackexchange is also very revealing. – JanKanis Jul 10 '12 at 09:47
  • I'd like to add that for *nearly all* applications (including salt generation) you don't need crypto-safe random numbers. – NikiC Jul 10 '12 at 12:27
  • @Somejan: I 'm not qualified to judge, but Wikipedia's "Disadvantages" section on MT says that it's a very good idea to seed MT with an LCG because it avoids the problematic case where MT is seeded with lots of zeroes and takes a lot of time to "break out" of that state. – Jon Jul 10 '12 at 12:38
  • @Jon: It's apparently a good idea to seed an MT with an LCG to improve the distribution of generated numbers. However, for cryptographic purposes this doesn't supply any additional entropy. If an attacker knows the PID and timestamp, he can just as easily predict the generated random numbers. – JanKanis Jul 10 '12 at 14:44
  • @NikiC: There are quite a number of applications where crypto-safe randomness is needed (where by crypto-safe I mean an attacker won't be able to predict the values), such as generating a session ID or a CSRF token. Salt generation is, indeed, not one of them. – JanKanis Jul 10 '12 at 14:47
  • @Somejan: yes indeed: encryption keys, random passwords, session keys, stream initialization vectors, nonces, secure unique IDs, etc... I would not agree with @NikiC's "nearly all" claim. The salts you use to defeat a rainbow attack do not need to be random but they do need to be unique and all the bugs in PHP's `mt_rand()` make me nervous to use it even for that. –  Jan 26 '13 at 22:02