Let’s Get Random: Under the Hood of PHP 7’s CSPRNG - Day Camp 4 Developers

Let’s Get Random: Under the Hood of PHP 7’s CSPRNG - Day Camp 4 Developers

Talk given at DC4D on June 2nd, 2017

Randomness is really important in many cryptographic contexts. Unfortunately true randomness is a non-trivial achievement for computers. In fact, using weak sources of randomness can leave your application open to myriad vulnerabilities. Enter: a good cryptographically secure pseudorandom number generator (CSPRNG).

We’ll discuss the importance of using good sources of randomness, the CSPRNG options we had in PHP 5.x, and how the new-hotness CSPRNG functions in PHP 7 work under the hood.

8c090cc1ccd623a146ddd9159b1bf7e2?s=128

Sammy Kaye Powers

June 02, 2017
Tweet

Transcript

  1. Random Under the hood of PHP 7’s Let’s get CSPRNG

    Sammy Kaye Powers 2017-06-02
  2. ext/standard/random.c

  3. The end

  4. Random? What is

  5. None
  6. Finish this sentence On the way home I got a

    flat ____. tire
  7. Think of a two-digit number both digits different from each

    other both digits odd between 1 and 100
  8. Are you thinking of… 37

  9. None
  10. 11 Random? What makes a number

  11. 2, 4, 6, 8, __ 10

  12. 1337, 42, 0, _ ?

  13. 1337, 42, 0, 1337, 42, 0, 1337, __ 42

  14. Random? What is isn’t Deterministic

  15. “True” Random Measuring atmospheric noise Counting the number of electrons

    coming off of a radioactive material
  16. None
  17. Can I haz random number?

  18. None
  19. None
  20. *sigh* Take this. 42

  21. None
  22. 0

  23. 2,4,8, 7,5,1 ?

  24. Number Generator …or “PRNG” for short Pseudorandom

  25. Pseudorandom? How’s that different than just random? Deterministic

  26. 2,4,8, 7,5,1 Generator Linear Congruential

  27. Generator Linear Congruential

  28. None
  29. None
  30. 2,4,8, 7,5,1,

  31. 2,4,8, 7,5,1, Deterministic

  32. https://xkcd.com/221/

  33. None
  34. None
  35. 8,7,5, 1,2,4,

  36. 1,2,4, 8,7,5, BUT!

  37. None
  38. 5,1,2,4,8,7,5, 1,2,4,8,7,5,1, 2,4,8,7,5,1,2, 4,8,7,5,1,2,4, 8,7,5,1,2,4,8, 7,5,1,2,4, Predictable

  39. LCG lcg_value() PHP has a combined

  40. PRNG? Is there a better

  41. Twister Mersenne mt_rand()

  42. None
  43. mt_rand() 724937621,955931554,1407935661,821438740,109344 9922,603009103,1540988686,1028238631,798475733, 1057939018,671583233,1853117923,98760648,112245 3373,534404057,900958085,1712824654,476385742,2 9956470,362833620,424798798,746223917,942003531 ,320462445,673296853,1351199651,141566289,16454 09515,995047403,1216151582,1115999460,175322091 7,1312071810,1553254094,1622498991,2080099801,1 704834715,1537620663,1357630828,1317892558,

    219,937-1
  44. None
  45. mt_rand(0,99) 83,9,64,28,62,48,83,47,46,53,37,26,21,91,61,32,58,1,89,60,65,97,42,56,6,47,76,1 2,98,11,36,61,62,60,43,67,6,16,73,15,39,38,56,19,66,56,98,72,91,24,57,94,8,26,7 3,55,17,14,84,89,39,11,13,48,71,98,89,63,9,95,74,9,81,85,97,24,14,14,77,22,96,4 3,61,91,61,58,19,71,8,49,18,92,38,34,9,36,91,59,14,4,58,59,29,74,52,41,36,67,82 ,67,11,0,58,51,37,4,45,56,35,50,78,91,27,39,80,27,28,95,2,82,51,72,27,41,43,74, 7,82,59,89,72,9,22,61,75,27,64,16,77,57,31,29,59,47,14,67,89,33,94,33,94,22,11, 62,9,13,61,45,78,29,3,11,99,91,52,79,63,64,43,99,53,22,16,10,53,57,15,84,16,30, 17,10,3,35,0,45,83,11,70,66,37,14,59,41,46,52,53,53,62,56,41,82,40,99,8,92,96,2 2,22,43,35,60,45,77,26,96,45,51,62,77,64,23,52,17,17,97,93,57,43,56,45,62,42,24

    ,62,1,59,38,70,13,34,32,48,47,1,42,48,18,2,59,47,53,10,3,66,68,93,4,53,85,20,77 ,63,43,45,16,15,77,73,89,11,64,76,30,46,91,1,85,96,19,63,70,62,35,58,95,63,38,7 8,83,8,97,22,2,28,51,25,29,98,62,74,59,95,79,74,66,47,35,83,56,49,25,32,25,46,1 3,69,77,30,94,24,31,68,23,64,47,28,33,65,69,16,0,98,37,85,93,60,24,10,54,50,42, 64,11,9,13,15,84,3,23,73,83,83,72,9,2,28,23,90,73,2,47,45,93,4,32,25,75,61,98,7 3,79,66,23,20,83,11,45,67,40,39,45,0,65,40,78,74,8,79,86,38,10,87,60,99,30,35,5 0,16,29,24,19,29,16,40,57,87,26,90,1,63,63,34,44,8,36,25,38,50,10,15,17,14,40,6 ,53,88,18,36,46,69,2,13,0,83,59,92,59,34,34,24,40,99,41,6,79,65,98,9,36,31,8,4, 89,98,91,80,42,10,26,72,40,50,39,25,33,45,24,70,54,89,91,53,23,12,20,40,21,25,5 5,48,11,3,84,42,5,7,21,58,85,18,52,92,94,69,20,49,3,8,55,57,4,38,52,37,64,55,82 ,98,5,75,84,35,14,99,74,23,41,69,55,53,22,52,6,68,35,38,73,52,22,52,86,79,15,38 ,3,20,99,36,23,77,33,80,16,97,54,88,11,77,77,99,70,26,5,75,87,4,23,8,50,79,61,5 5,80,25,58,79,25,56,9,81,6,42,27,90,58,6,62,74,25,79,81,61,23,54,92,53,16,66,22 ,49,77,97,84,25,49,32,49,65,51,1,93,63,68,69,67,10,44,99,44,42,89,35,24, 624 = busted
  46. echo mt_rand(0,99); 11

  47. echo mt_rand(0,99); 9

  48. echo mt_rand(0,99); 60

  49. mt_srand(10); echo mt_rand(0,99); 21

  50. mt_srand(10); echo mt_rand(0,99); 21

  51. mt_srand(10); echo mt_rand(0,99); 21

  52. CSRF Take for example Tokens

  53. Cross-site request forgery (CSRF) tokens help prevent unauthorized requests on

    a user’s behalf.
  54. A CSRF token must be unique and unpredictable.

  55. None
  56. None
  57. None
  58. I’ll just let PHP seed mt_rand() for me. Bad idea

    jeans *Old SNL skit reference
  59. None
  60. Cryptographically Pseudorandom Secure Number Generator

  61. CSPRNG or…

  62. “See Spring” or…

  63. Unicorn Magical

  64. Uses seeds that are really really really really ridiculously hard

    to guess
  65. impossible It’s values are to predict in practice 42 82

    Suitable for use in cryptographic contexts.
  66. mythical Where can we find this creature?

  67. CSPRNG options in 5.x

  68. openssl_random_pseudo_bytes() mcrypt_create_iv() /dev/urandom

  69. openssl_random_pseudo_bytes() mcrypt_create_iv() /dev/urandom

  70. Since the UNIX fork() system call duplicates the entire process

    state, a random number generator which does not take this issue into account will produce the same sequence of random numbers in both the parent and the child […], leading to cryptographic disaster… https://wiki.openssl.org/index.php/Random_fork-safety
  71. OpenSSL’s be like 42 CSPRNG

  72. OpenSSL cannot fix the fork-safety problem because its not in

    a position to do so. However, there are [solutions] available and they are listed below. https://wiki.openssl.org/index.php/Random_fork-safety
  73. Don't use RAND_bytes https://wiki.openssl.org/index.php/Random_fork-safety

  74. Instead, you can read directly from /dev/random, /dev/urandom or /dev/srandom;

    or use CryptGenRandom on Windows systems. https://wiki.openssl.org/index.php/Random_fork-safety
  75. mcrypt_create_iv() /dev/urandom openssl_random_pseudo_bytes()

  76. None
  77. None
  78. None
  79. /dev/urandom openssl_random_pseudo_bytes() mcrypt_create_iv()

  80. open_basedir=/foo/dir

  81. openssl_random_pseudo_bytes() mcrypt_create_iv() /dev/urandom

  82. CSPRNG New hotness 7

  83. CSPRNG random_int() random_bytes()

  84. random_int(0,99) 6,17,6,9,17,53,58,98,46,44,62,9,76,65,46,21,42,5,65,34,11,96,85,7,46,89,98,9,9, 80,8,76,87,18,24,68,16,61,27,39,30,32,4,83,83,23,96,27,13,47,6,99,16,40,2,75,27 ,3,79,68,75,60,50,70,63,17,75,29,79,57,9,48,18,86,95,25,40,52,20,86,6,48,94,27, 76,14,9,27,62,14,68,58,12,18,63,19,84,47,7,13,63,28,66,55,2,75,44,92,11,85,51,1 7,42,57,22,4,53,7,3,76,48,55,95,7,45,33,87,36,11,17,66,6,46,87,57,48,22,31,65,5 ,26,10,47,82,97,74,25,32,63,60,29,53,13,24,56,54,52,86,67,4,94,35,48,73,35,45,2 4,74,74,83,49,70,41,49,20,60,29,49,30,35,38,63,4,86,72,97,26,22,36,95,59,94,24, 89,73,46,14,73,51,93,93,39,13,80,9,30,24,20,30,63,20,64,97,29,7,2,82,96,42,61,5 3,28,49,12,90,71,58,72,63,49,32,69,76,50,62,88,31,26,72,79,19,15,3,39,27,80,16,

    65,62,53,82,59,23,85,95,41,68,86,3,92,76,91,88,12,20,96,14,35,50,94,24,23,44,55 ,78,65,81,7,1,86,32,58,46,97,43,78,9,51,1,6,79,73,49,13,40,21,90,14,9,70,95,88, 37,85,14,7,29,42,55,81,46,39,41,45,81,11,93,26,89,4,98,35,30,36,74,97,18,85,97, 23,52,64,88,20,89,12,25,19,21,21,50,60,50,43,84,1,52,5,19,2,86,38,51,48,30,55,9 0,93,97,52,84,29,58,96,78,37,24,14,72,81,9,82,26,83,83,17,35,15,9,87,95,51,71,4 8,9,45,13,61,98,3,18,96,99,28,74,47,58,71,89,68,57,51,86,90,38,21,72,72,30,22,1 3,88,25,48,45,62,59,81,32,10,54,82,60,90,17,98,41,73,98,60,22,99,66,32,41,82,62 ,91,3,85,91,21,17,98,19,48,50,24,67,3,14,62,55,35,99,95,83,76,12,51,77,61,24,24 ,60,15,31,47,24,27,97,98,70,6,24,25,20,23,67,72,55,47,19,53,50,38,22,76,37,63,8 2,67,52,3,75,84,84,71,49,79,26,89,11,77,55,92,32,81,38,23,54,9,40,80,75,20,7,58 ,37,72,75,59,46,32,41,82,90,72,59,5,42,2,94,44,44,4,15,37,29,24,10,51,18,8,42,5 6,9,68,31,99,7,77,59,8,74,80,11,15,93,81,5,72,44,49,39,25,4,18,98,0,93,42,78,36 ,57,47,16,49,2,85,6,31,17,81,10,54,40,95,68,31,80,29,41,86,32,9,58,96,62,79,25, 6,45,56,54,0,61,74,90,12,34,11,56,3,41,39,84,32,30,42,81,36,43,5,
  85. bin2hex(random_bytes(16)) f7f5289027cb6c5116d 2d3cc78e5819c

  86. You’re not strong until you’re crypto-strong!

  87. CSPRNG under the hood

  88. None
  89. On Windows: CryptGenRandom On BSD: arc4random_buf() On Linux: getrandom(2) syscall

    Read directly from /dev/urandom
  90. Fail Closed

  91. /dev/urandom So what is this thing?

  92. /dev/urandom Gathers environmental noise from the system like… …device drivers,

    inter-keyboard timings, inter-interrupt timings from some interrupts, and other events which are both (a) non-deterministic and (b) hard for an outside observer to measure. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/char/random.c
  93. CSPRNG random_bytes() random_int() 7 /dev/urandom Powered by

  94. Still on 5.x? paragonie/random_compat Polyfill for PHP 7 CSPRNG

  95. TL;DR Never use LCG, MT, or any other PRNG in

    cryptographic contexts Only use a CSPRNG like /dev/urandom for crypto Use random_bytes() & random_int() in PHP (or install paragonie/random_compat)
  96. More Resources

  97. Recommendation for the Entropy Sources Used for Random Bit Generation

    Second Draft - NIST SP 800-90B http://csrc.nist.gov/publications/drafts/800-90/sp800-90b_second_draft.pdf
  98. New & improved man pages for /dev/urandom http://man7.org/linux/man-pages/man7/random.7.html

  99. Myths about /dev/urandom Thomas Hühn https://www.2uo.de/myths-about-urandom/

  100. Cracking Random Number Generators Three-part blog post series James Roper

    https://jazzy.id.au/2010/09/20/cracking_random_number_generators_part_1.html
  101. How I Met Your Girlfriend DEF CON 18 Samy Kamkar

    https://www.youtube.com/watch?v=fWk_rMQiDGc
  102. Weak RNG in PHP session ID generation leads to session

    hijacking Andreas Bogk http://seclists.org/fulldisclosure/2010/Mar/519
  103. THANKS! SAMMY KAYE POWERS @SammyK SammyK.me Host of @PHPRoundtable West

    Coast Swing @ChiPHPUG Hire me! :)