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

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. You Shall (Maybe) Pass!
    Eric Mann

    View Slide

  2. Poster by DirectArtPrint - https://amzn.to/2ZYAMGq

    View Slide

  3. Authentication

    View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. View Slide

  10. Password Strength

    View Slide

  11. (Full image slide with caption)
    Password Strength - xkcd - https://xkcd.com/936/

    View Slide

  12. Information Entropy - https://www.itdojo.com/a-somewhat-brief-explanation-of-password-entropy/

    View Slide

  13. Restrict passwords
    obtained from
    previously breached
    corpuses

    View Slide

  14. Have I Been Pwned - https://haveibeenpwned.com/

    View Slide

  15. Have I Been Pwned Password API -
    https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/#cloudflareprivacyandkanonymity

    View Slide

  16. Brute Force Protection

    View Slide

  17. View Slide

  18. View Slide

  19. $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;

    View Slide

  20. $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;

    View Slide

  21. Secure Remote Passwords

    View Slide

  22. View Slide

  23. PHP Example … in the July 2018 issue of php[architect]: https://www.phparch.com/magazine/2018-2/july/

    View Slide

  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

    View Slide

  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)

    View Slide

  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)

    View Slide

  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)

    View Slide

  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)

    View Slide

  29. The node-sodium project is a JS port of Libsodium for use on Node-powered servers.

    View Slide

  30. The libsodium.js project uses transpiling to convert the raw C code directly to WebAssembly for use in the browser!

    View Slide

  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

    View Slide

  32. Questions?

    View Slide

  33. Thank you
    [email protected] | 503.925.6266

    View Slide