Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Sammy Kaye Powers

June 02, 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-06-02

    View Slide

  2. ext/standard/random.c

    View Slide

  3. The end

    View Slide

  4. Random?
    What is

    View Slide

  5. View Slide

  6. Finish this sentence
    On the way home
    I got a flat ____.
    tire

    View Slide

  7. Think of a two-digit number
    both digits different from each other
    both digits odd
    between 1 and 100

    View Slide

  8. Are you thinking of…
    37

    View Slide

  9. View Slide

  10. 11
    Random?
    What makes a number

    View Slide

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

    View Slide

  12. 1337, 42, 0, _
    ?

    View Slide

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

    View Slide

  14. Random?
    What is isn’t
    Deterministic

    View Slide

  15. “True” Random
    Measuring atmospheric noise
    Counting the number of electrons
    coming off of a radioactive material

    View Slide

  16. View Slide

  17. Can I haz
    random number?

    View Slide

  18. View Slide

  19. View Slide

  20. *sigh* Take this.
    42

    View Slide

  21. View Slide

  22. 0

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  27. Generator
    Linear Congruential

    View Slide

  28. View Slide

  29. View Slide

  30. 2,4,8,
    7,5,1,

    View Slide

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

    View Slide

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

    View Slide

  33. View Slide

  34. View Slide

  35. 8,7,5,
    1,2,4,

    View Slide

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

    View Slide

  37. View Slide

  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

    View Slide

  39. LCG
    lcg_value()
    PHP has a combined

    View Slide

  40. PRNG?
    Is there a better

    View Slide

  41. Twister
    Mersenne
    mt_rand()

    View Slide

  42. View Slide

  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

    View Slide

  44. View Slide

  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

    View Slide

  46. echo mt_rand(0,99);
    11

    View Slide

  47. echo mt_rand(0,99);
    9

    View Slide

  48. echo mt_rand(0,99);
    60

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  52. CSRF
    Take for example
    Tokens

    View Slide

  53. Cross-site request forgery
    (CSRF) tokens help prevent
    unauthorized requests on
    a user’s behalf.

    View Slide

  54. A CSRF token must be
    unique and unpredictable.

    View Slide

  55. View Slide

  56. View Slide

  57. View Slide

  58. I’ll just let PHP seed
    mt_rand() for me.
    Bad idea jeans
    *Old SNL skit reference

    View Slide

  59. View Slide

  60. Cryptographically
    Pseudorandom
    Secure
    Number Generator

    View Slide

  61. CSPRNG
    or…

    View Slide

  62. “See Spring”
    or…

    View Slide

  63. Unicorn
    Magical

    View Slide

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

    View Slide

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

    Suitable for use in
    cryptographic contexts.

    View Slide

  66. mythical
    Where can we find this
    creature?

    View Slide

  67. CSPRNG
    options in
    5.x

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  71. OpenSSL’s
    be like
    42


    CSPRNG


    View Slide

  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

    View Slide

  73. Don't use
    RAND_bytes
    https://wiki.openssl.org/index.php/Random_fork-safety

    View Slide

  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

    View Slide

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

    View Slide

  76. View Slide

  77. View Slide

  78. View Slide

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

    View Slide

  80. open_basedir=/foo/dir

    View Slide

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

    View Slide

  82. CSPRNG
    New hotness
    7

    View Slide

  83. CSPRNG
    random_int()
    random_bytes()

    View Slide

  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,

    View Slide

  85. bin2hex(random_bytes(16))
    f7f5289027cb6c5116d
    2d3cc78e5819c

    View Slide

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

    View Slide

  87. CSPRNG
    under the hood

    View Slide

  88. View Slide

  89. On Windows: CryptGenRandom
    On BSD: arc4random_buf()
    On Linux: getrandom(2) syscall
    Read directly from /dev/urandom

    View Slide

  90. Fail
    Closed

    View Slide

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

    View Slide

  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

    View Slide

  93. CSPRNG
    random_bytes()
    random_int()
    7
    /dev/urandom
    Powered by

    View Slide

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

    View Slide

  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)

    View Slide

  96. More Resources

    View Slide

  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

    View Slide

  98. New & improved man pages for
    /dev/urandom
    http://man7.org/linux/man-pages/man7/random.7.html

    View Slide

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

    View Slide

  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

    View Slide

  101. How I Met Your Girlfriend
    DEF CON 18
    Samy Kamkar
    https://www.youtube.com/watch?v=fWk_rMQiDGc

    View Slide

  102. Weak RNG in PHP session ID generation
    leads to session hijacking
    Andreas Bogk
    http://seclists.org/fulldisclosure/2010/Mar/519

    View Slide

  103. THANKS!
    SAMMY KAYE POWERS
    @SammyK
    SammyK.me
    Host of @PHPRoundtable
    West Coast Swing
    @ChiPHPUG
    Hire me! :)

    View Slide