Authentication and Password Management

Dr. Greg M. Bernstein

Updated October 19th, 2021

Authentication

Authentication Background

From OWASP:

Authentication is the process of verification that an individual, entity or website is who it claims to be. Authentication in the context of web applications is commonly performed by submitting a user name or ID and one or more items of private information that only a given user should know.

References

Password Based Authentication

Common Attacks

  • Brute Force (too short)
  • Guessing Attacks (too common)
  • Credential Stuffing (exposed in other breaches)

Countering Attacks

  • Password length and content requirements
  • Checking against common passwords
  • Credential Stuffing – For users: don’t use the same password for two different sites, for websites see Credential Stuffing Prevention Cheat Sheet

Bad Passwords

  • There are lists of the most commonly used passwords in various forms for security testing (or for evil)

  • The top 20: 123456, password, 12345678, qwerty, 123456789, 12345, 1234, 111111, 1234567, dragon, 123123, baseball, abc123, football, monkey, letmein, 696969, shadow, master, 666666

  • Why not just try them all?

Password Storage and Theft

Issues

  • Passwords used for web site/app authorization need to be kept on the server
  • Many attacks focus on trying to get at these “assets”
  • Even for a large sites with millions of users the entire password/user database can fit on a moderate sized memory stick (insider threat)

Encryption and Such

  • User passwords should never be stored in the “clear”
  • Most common encryption algorithms are designed to be very fast and efficient
  • This poses special problems for password storage

Brute Force and Guess Attacks

Given a database of “encrypted” stolen passwords couldn’t I just try encrypting all 10 Million of the most common passwords and look for matches?

Yes, encryption and hash algorithms are designed to be fast so going through the 10 million item database and looking for matches across the stolen password database is feasible. This is also known as a “dictionary attack”.

A Grain of Salt

Salt: Some binary data that we add and store with each password to make dictionary attacks more difficult.

Psuedo-Code

[protected form] = [salt] + protect([protection func], [salt] + [password])

How does this help?

Now the attacker has run the protection (encryption/hash) function with the salt against the entire “dictionary” with the “salt” for each stored password

Rules for the Salt

From OWASP:

  • Generate a unique salt upon creation of each stored credential
  • Use cryptographically-strong random data;
  • As storage permits, use a 32 byte or 64 byte salt

Random Numbers

Two very different types of random numbers in computing:

  • Those used in computer simulation must be very fast, have a wide range of “good” statistical properties. The sequences generated also must be repeatable given the same “seed”. Example: Math.random() in JavaScript.

  • Cryptographically random data. These must not be “predictable” in any way. They usually are generated by performing some cryptographic operations on sources of “natural” randomness. Example: Node.js crypto.randomBytes(size[, callback])

Special Crypto Functions for Passwords

Adaptive one-way functions

Make password encryption harder

Adaptive one-way functions compute a one-way (irreversible) transform. Each function allows configuration of ‘work factor’. Underlying mechanisms used to achieve irreversibility and govern work factors (such as time, space, and parallelism) vary between functions

Argon2 paper

Why Different Algorithms

  • Some may not be available for your platform
  • Many are based on C/C++ libraries
  • There is a JavaScript only version of bcryptjs that you can use if you can’t get argon2 to install.

Basic Server Password Processing

Passwords on the Server

  • Never, ever, ever store unencrypted passwords on a server.

  • You should not use just any encryption algorithm

    • Most encryption algorithms are designed to be fast and secure
    • Being fast with password encryption leaves a system open to dictionary attacks
  • We will use bcryptjs for class purposes.

bcryptjs Password Hashing

  • npm install bcryptjs --save
const bcrypt = require('bcryptjs');
// Hashing a password prior to storage
let salt = bcrypt.genSaltSync(10); // New salt everytime!
let passHash = bcrypt.hashSync("MyPassWordThing", salt);
console.log(passHash);

bcryptjs Verification

const bcrypt = require('bcryptjs');
// Verfying hash; I got these from running the hashing method
hash1 = "$2a$10$J.CgzRJ1rsQNqF3ttS1m8uf2IVNntKdnfP3qIU7KW48HUtGX/jSPm";
hash2 = "$2a$10$w.fRaM4V2v4KivCm5xRimOaEBz3xOhxkOtpKN8HnGXx/cz8Zi7P2C";

let verified = bcrypt.compareSync("MyPassWordThing", hash1);
console.log(`Verified against hash1: ${verified}`);
verified = bcrypt.compareSync("MyPassWordThing", hash2);
console.log(`Verified against hash2: ${verified}`);
verified = bcrypt.compareSync("MyPassWordThinh", hash2);
console.log(`Verified against hash2: ${verified}`);

Creating Development User Data

For development purposes we want a user/password data that acts like the “real thing” without us having to come up with a whole set of admin pages and backend processing

  • Put together a list of fake users, passwords, and any other information your application will need about them.

  • Or use a tool like the Mimesis Fake Data Generator to help you.

Example Fake User Data

Part of the students2.json fake data file:

[
  {
    "netid": "zp4605",
    "firstName": "Samual",
    "lastName": "Preston",
    "email": "carcass1991@outlook.com",
    "password": "5ag1~;fl"
  },
  {
    "netid": "su2599",
    "firstName": "Eldridge",
    "lastName": "Boyle",
    "email": "cheques2002@yandex.com",
    "password": "}amjrFu="
  },
  {
    "netid": "vd5188",
    "firstName": "Darnell",
    "lastName": "Barr",
    "email": "gals2062@yahoo.com",
    "password": "#|`0lJ#O"
  },
  {
    "netid": "ga6277",
    "firstName": "Duane",
    "lastName": "Pate",
    "email": "camel1848@gmail.com",
    "password": "[i#_l9}'"
  }]

Dealing with Passwords

  • The passwords in our data are “in the clear”.

  • We need to remove the password fields and add a field to hold the secure hash of the password.

Secured User Data Example

Passwords replaced with secure hash:

[
  {
    "netid": "qy6139",
    "firstName": "Buena",
    "lastName": "Henderson",
    "email": "antisun1921@outlook.com",
    "passHash": "$2a$10$ITfmh3oePyOBBQm8SwVkNOzUg8igwAdd54VXPdG9BDRH7C3gOLDmO"
  },
  {
    "netid": "kr0259",
    "firstName": "Sharika",
    "lastName": "Perry",
    "email": "deer2037@outlook.com",
    "passHash": "$2a$10$Cm1Q5bHkNpMoshoNMkKglee3fj7fds62y9xXmJLkkazUSNbmlY5kK"
  }
]
// reveal.js plugins