Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

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.

Eric Mann

May 21, 2019
Tweet

More Decks by Eric Mann

Other Decks in Programming

Transcript

  1. <?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;
  2. <?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;
  3. PHP Example … in the July 2018 issue of php[architect]:

    https://www.phparch.com/magazine/2018-2/july/
  4. $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
  5. $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)
  6. $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)
  7. $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)
  8. $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)
  9. The libsodium.js project uses transpiling to convert the raw C

    code directly to WebAssembly for use in the browser!
  10. 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