You Shall (Maybe) Pass!

You Shall (Maybe) Pass!

The first point of contact most users have with your application is the login screen. It’s a ubiquitous interface, and approaches for handling authentication are legion. A plethora of options for authentication doesn’t mean it’s an easy practice, though. Together, we’ll review authentication from first principles, starting with password-based systems and diving deeper into defensive hashing techniques and the edge cases developers need to consider when protecting user data. We’ll also go deep into the secure remote password flow, leveraging the technique both from native PHP and a JavaScript client-side implementation.

46093583d8895095adb1b0071c505af2?s=128

Eric Mann

May 21, 2019
Tweet

Transcript

  1. 4.
  2. 5.
  3. 6.
  4. 7.
  5. 8.
  6. 9.
  7. 17.
  8. 18.
  9. 19.

    <?php $timeTarget = 0.05; // 50 milliseconds $cost = 8;

    do { $cost++; $start = microtime(true); password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]); $end = microtime(true); } while (($end - $start) < $timeTarget); echo "Appropriate Cost Found: " . $cost;
  10. 20.

    <?php $timeTarget = 0.05; // 50 milliseconds $cost = 1;

    do { $cost++; $start = microtime(true); password_hash("test", PASSWORD_ARGON2I, ["time_cost" => $cost]); $end = microtime(true); } while (($end - $start) < $timeTarget); echo "Appropriate Cost Found: " . $cost;
  11. 22.
  12. 23.

    PHP Example … in the July 2018 issue of php[architect]:

    https://www.phparch.com/magazine/2018-2/july/
  13. 24.

    $salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES); $seed = sodium_crypto_pwhash(/* ... */); $keypair =

    sodium_crypto_kx_seed_keypair($seed); $public_key = sodium_crypto_kx_publickey($keypair); // POST this data to the server to register $registration = [ 'identifier' => $email, 'salt' => sodium_bin2hex($salt), 'public_key' => sodium_bin2hex($public_key) ]; SRP - Client Registration
  14. 25.

    $user = get_user_from_database($email); $keypair = sodium_crypto_kx_keypair(); $public_key = sodium_crypto_kx_publickey($keypair); $keys

    = sodium_crypto_kx_server_session_keys($keypair, $user->key); $client_secret = $keys[1]; $server_secret = $keys[0]; $message = random_bytes(32); $hash = sodium_crypto_generichash($message, $server_secret); $proof = sodium_bin2hex($message . $hash); SRP - Initialize Auth Challenge (Server)
  15. 26.

    $keys = sodium_crypto_kx_server_session_keys($keypair, $server_key); $client_secret = $keys[0]; $server_secret = $keys[1];

    $server_proof = sodium_hex2bin($server_proof); $message = substr($server_proof, 0, 32); $hash = substr($server_proof, 32); if (!hash_equals( sodium_crypto_generichash($message, $server_secret), $hash )) { exit; } SRP - Complete Auth Challenge (Client)
  16. 27.

    $keys = sodium_crypto_kx_server_session_keys($keypair, $server_key); $client_secret = $keys[0]; $server_secret = $keys[1];

    /* ... */ $message = random_bytes(32); $hash = sodium_crypto_generichash($message, $client_secret); $proof = sodium_bin2hex($message . $hash); SRP - Complete Auth Challenge (Client)
  17. 28.

    $client_proof = sodium_hex2bin($proof); $message = substr($client_proof, 0, 32); $hash =

    substr($client_proof, 32); if (!hash_equals( sodium_crypto_generichash($message, $client_secret), $hash )) { exit; } // Store the user's email in a session for subsequent requests $_SESSION['identifier'] = $email; SRP - Complete Auth Challenge (Server)
  18. 30.

    The libsodium.js project uses transpiling to convert the raw C

    code directly to WebAssembly for use in the browser!
  19. 31.

    In Review ... Something you are, know (, and have)

    Strong passwords are a must Strong hashing is a must If you can, avoid ever seeing or interacting with passwords