$30 off During Our Annual Pro Sale. View Details »

Let's Get Random: Under the Hood of PHP 7's CSPRNG - PNWPHP 2017

Let's Get Random: Under the Hood of PHP 7's CSPRNG - PNWPHP 2017

Talk given at Pacific Northwest PHP 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-goodness CSPRNG functions in PHP 7 work under the hood.

Sammy Kaye Powers

September 08, 2017
Tweet

More Decks by Sammy Kaye Powers

Other Decks in Programming

Transcript

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

    Sammy Kaye Powers 2017-09-08
  2. joind.in/talk/da53c @SammyK #PNWPHP Slides Get the joind.in/talk/da53c

  3. joind.in/talk/da53c @SammyK #PNWPHP ext/standard/random.c

  4. joind.in/talk/da53c @SammyK #PNWPHP The end

  5. joind.in/talk/da53c @SammyK #PNWPHP Random? What is

  6. joind.in/talk/da53c @SammyK #PNWPHP

  7. joind.in/talk/da53c @SammyK #PNWPHP Finish this sentence On the way home

    I got a flat ____. tire
  8. joind.in/talk/da53c @SammyK #PNWPHP Think of a two-digit number both digits

    different from each other both digits odd between 1 and 100
  9. joind.in/talk/da53c @SammyK #PNWPHP Are you thinking of… 37

  10. joind.in/talk/da53c @SammyK #PNWPHP

  11. joind.in/talk/da53c @SammyK #PNWPHP 11 random? What makes a number

  12. joind.in/talk/da53c @SammyK #PNWPHP 2, 4, 6, 8, __ 10

  13. joind.in/talk/da53c @SammyK #PNWPHP 1337, 42, 0, _ ?

  14. joind.in/talk/da53c @SammyK #PNWPHP 1337, 42, 0, 1337, 42, 0, 1337,

    __ 42
  15. joind.in/talk/da53c @SammyK #PNWPHP Random? What is isn’t Deterministic

  16. joind.in/talk/da53c @SammyK #PNWPHP “True” Random Measurement of atmospheric noise Count

    of the number of electrons coming off of a radioactive material
  17. None
  18. joind.in/talk/da53c @SammyK #PNWPHP Can I haz random number?

  19. joind.in/talk/da53c @SammyK #PNWPHP

  20. joind.in/talk/da53c @SammyK #PNWPHP

  21. joind.in/talk/da53c @SammyK #PNWPHP *sigh* Take this. 42

  22. joind.in/talk/da53c @SammyK #PNWPHP

  23. joind.in/talk/da53c @SammyK #PNWPHP 0

  24. joind.in/talk/da53c @SammyK #PNWPHP 2,4,8, 7,5,1 ?

  25. joind.in/talk/da53c @SammyK #PNWPHP Number Generator …or “PRNG” for short Pseudorandom

  26. joind.in/talk/da53c @SammyK #PNWPHP Pseudorandom? How’s that different than just random?

    Deterministic
  27. joind.in/talk/da53c @SammyK #PNWPHP 2,4,8, 7,5,1 Generator Linear Congruential

  28. joind.in/talk/da53c @SammyK #PNWPHP Generator Linear Congruential

  29. joind.in/talk/da53c @SammyK #PNWPHP

  30. joind.in/talk/da53c @SammyK #PNWPHP The modulus The multiplier The increment The

    seed
  31. joind.in/talk/da53c @SammyK #PNWPHP

  32. joind.in/talk/da53c @SammyK #PNWPHP

  33. joind.in/talk/da53c @SammyK #PNWPHP 2,4,8, 7,5,

  34. joind.in/talk/da53c @SammyK #PNWPHP 2,4,8, 7,5, Deterministic

  35. joind.in/talk/da53c @SammyK #PNWPHP https://xkcd.com/221/

  36. joind.in/talk/da53c @SammyK #PNWPHP

  37. joind.in/talk/da53c @SammyK #PNWPHP

  38. joind.in/talk/da53c @SammyK #PNWPHP 8,7,5, 1,2,

  39. joind.in/talk/da53c @SammyK #PNWPHP 1,2,4, 8,7, BUT!

  40. joind.in/talk/da53c @SammyK #PNWPHP

  41. 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

  42. joind.in/talk/da53c @SammyK #PNWPHP LCG lcg_value() PHP has a combined

  43. joind.in/talk/da53c @SammyK #PNWPHP PRNG? Is there a better

  44. joind.in/talk/da53c @SammyK #PNWPHP Twister Mersenne mt_rand()

  45. joind.in/talk/da53c @SammyK #PNWPHP

  46. 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
  47. joind.in/talk/da53c @SammyK #PNWPHP

  48. 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
  49. echo mt_rand(0,99); 11

  50. echo mt_rand(0,99); 9

  51. echo mt_rand(0,99); 60

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

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

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

  55. joind.in/talk/da53c @SammyK #PNWPHP CSRF Take for example Tokens

  56. joind.in/talk/da53c @SammyK #PNWPHP Cross-site request forgery (CSRF) tokens help prevent

    unauthorized requests on a user’s behalf.
  57. joind.in/talk/da53c @SammyK #PNWPHP A CSRF token must be unique and

    unpredictable.
  58. joind.in/talk/da53c @SammyK #PNWPHP

  59. joind.in/talk/da53c @SammyK #PNWPHP

  60. joind.in/talk/da53c @SammyK #PNWPHP

  61. joind.in/talk/da53c @SammyK #PNWPHP I’ll just let PHP seed mt_rand() for

    me. Bad idea jeans *Old SNL skit reference
  62. joind.in/talk/da53c @SammyK #PNWPHP

  63. joind.in/talk/da53c @SammyK #PNWPHP What about rand() you ask?

  64. joind.in/talk/da53c @SammyK #PNWPHP Nope

  65. joind.in/talk/da53c @SammyK #PNWPHP rand() mt_rand() …in PHP 7.0 & below

  66. joind.in/talk/da53c @SammyK #PNWPHP rand() Uses the system PRNG (unreliable &

    inconsistent) Is a PRNG (totes predictable) Uniform distribution issues
  67. joind.in/talk/da53c @SammyK #PNWPHP Uniform Distribution

  68. joind.in/talk/da53c @SammyK #PNWPHP 0 0.05 0.1 0.15 0.2 1 2

    3 4 5 6
  69. joind.in/talk/da53c @SammyK #PNWPHP 0 0.1 0.2 0.3 0.4 1 2

    3 4 5 6
  70. joind.in/talk/da53c @SammyK #PNWPHP Uniform Distribution == True Random

  71. joind.in/talk/da53c @SammyK #PNWPHP mt_rand() Implements the MT algorithm incorrectly Is

    a PRNG (totes predictable) Has a modulo bias
  72. joind.in/talk/da53c @SammyK #PNWPHP Modulo Bias

  73. joind.in/talk/da53c @SammyK #PNWPHP 6 % 3 = 0 8 %

    3 = 2 Modulo Operator
  74. joind.in/talk/da53c @SammyK #PNWPHP Random # between 0 & 1 n

    % 2 = 0 or 1 Use mod 2
  75. joind.in/talk/da53c @SammyK #PNWPHP rand_src() = 1, 2, or 3 2

    % 2 = 0 3 % 2 = 1 1 is more likely 1 % 2 = 1
  76. joind.in/talk/da53c @SammyK #PNWPHP rand() mt_rand() …in PHP 7.1 & above

  77. joind.in/talk/da53c @SammyK #PNWPHP mt_rand() Fixes bug in MT algorithm implementation

    Is a PRNG (totes predictable)
  78. joind.in/talk/da53c @SammyK #PNWPHP They’re totes samezies! rand() mt_rand() ===

  79. joind.in/talk/da53c @SammyK #PNWPHP

  80. joind.in/talk/da53c @SammyK #PNWPHP rand() mt_rand() Both suffer from modulo bias

    &
  81. joind.in/talk/da53c @SammyK #PNWPHP Seeds aren’t impossible to predict

  82. joind.in/talk/da53c @SammyK #PNWPHP Entropy *Could be it’s own talk

  83. joind.in/talk/da53c @SammyK #PNWPHP A measure of how accurately we’re able

    to predict the next value in a sequence.* * oversimplification
  84. joind.in/talk/da53c @SammyK #PNWPHP High entropy harder to predict Low entropy

    easier to predict
  85. joind.in/talk/da53c @SammyK #PNWPHP Cryptographically Pseudorandom Secure Number Generator

  86. joind.in/talk/da53c @SammyK #PNWPHP CSPRNG or…

  87. joind.in/talk/da53c @SammyK #PNWPHP “See Spring” or…

  88. Unicorn Magical

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

    to guess
  90. joind.in/talk/da53c @SammyK #PNWPHP High Entropy wee!

  91. joind.in/talk/da53c @SammyK #PNWPHP impossible It’s values are to predict in

    practice 42 82 Suitable for use in cryptographic contexts.
  92. mythical Where can we find this creature?

  93. joind.in/talk/da53c @SammyK #PNWPHP CSPRNG options in 5.x

  94. joind.in/talk/da53c @SammyK #PNWPHP openssl_random_pseudo_bytes() mcrypt_create_iv() /dev/urandom

  95. joind.in/talk/da53c @SammyK #PNWPHP openssl_random_pseudo_bytes() mcrypt_create_iv() /dev/urandom

  96. joind.in/talk/da53c @SammyK #PNWPHP 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
  97. joind.in/talk/da53c @SammyK #PNWPHP OpenSSL’s be like 42 CSPRNG

  98. joind.in/talk/da53c @SammyK #PNWPHP 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
  99. joind.in/talk/da53c @SammyK #PNWPHP Don't use RAND_bytes https://wiki.openssl.org/index.php/Random_fork-safety

  100. joind.in/talk/da53c @SammyK #PNWPHP 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
  101. joind.in/talk/da53c @SammyK #PNWPHP mcrypt_create_iv() /dev/urandom openssl_random_pseudo_bytes()

  102. joind.in/talk/da53c @SammyK #PNWPHP

  103. joind.in/talk/da53c @SammyK #PNWPHP

  104. joind.in/talk/da53c @SammyK #PNWPHP

  105. joind.in/talk/da53c @SammyK #PNWPHP /dev/urandom openssl_random_pseudo_bytes() mcrypt_create_iv()

  106. joind.in/talk/da53c @SammyK #PNWPHP open_basedir=/foo/dir

  107. joind.in/talk/da53c @SammyK #PNWPHP openssl_random_pseudo_bytes() mcrypt_create_iv() /dev/urandom

  108. joind.in/talk/da53c @SammyK #PNWPHP CSPRNG New goodness 7

  109. joind.in/talk/da53c @SammyK #PNWPHP CSPRNG random_int() random_bytes()

  110. 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,
  111. joind.in/talk/da53c @SammyK #PNWPHP bin2hex(random_bytes(16)) f7f5289027cb6c5116d 2d3cc78e5819c

  112. joind.in/talk/da53c @SammyK #PNWPHP You’re not strong until you’re crypto-strong!

  113. CSPRNG under the hood

  114. None
  115. joind.in/talk/da53c @SammyK #PNWPHP On Windows: CryptGenRandom On BSD: arc4random_buf() On

    Linux: getrandom(2) syscall Read directly from /dev/urandom
  116. Fail Closed

  117. joind.in/talk/da53c @SammyK #PNWPHP /dev/urandom So what is this thing?

  118. /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
  119. joind.in/talk/da53c @SammyK #PNWPHP CSPRNG random_bytes() random_int() 7 /dev/urandom Powered by

  120. joind.in/talk/da53c @SammyK #PNWPHP Still on 5.x? paragonie/random_compat Polyfill for PHP

    7 CSPRNG
  121. joind.in/talk/da53c @SammyK #PNWPHP 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)
  122. joind.in/talk/da53c @SammyK #PNWPHP More Resources

  123. joind.in/talk/da53c @SammyK #PNWPHP 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
  124. joind.in/talk/da53c @SammyK #PNWPHP New & improved man pages for /dev/urandom

    http://man7.org/linux/man-pages/man7/random.7.html
  125. joind.in/talk/da53c @SammyK #PNWPHP Myths about /dev/urandom Thomas Hühn https://www.2uo.de/myths-about-urandom/

  126. joind.in/talk/da53c @SammyK #PNWPHP 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
  127. joind.in/talk/da53c @SammyK #PNWPHP How I Met Your Girlfriend DEF CON

    18 Samy Kamkar https://www.youtube.com/watch?v=fWk_rMQiDGc
  128. joind.in/talk/da53c @SammyK #PNWPHP Weak RNG in PHP session ID generation

    leads to session hijacking Andreas Bogk http://seclists.org/fulldisclosure/2010/Mar/519
  129. @SammyK SammyK.me THANKS! SAMMY KAYE POWERS Host of @PHPRoundtable @ChiPHPUG

    West Coast Swing /talk/da53c I have stickers!