Dr. Greg M. Bernstein
Updated October 19th, 2021
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.
Authentication Cheat Sheet. The introduction defines authentication and relates to session management.
Password and Credential Management in 2018 Latest and greatest techniques!
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?
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”.
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])
Now the attacker has run the protection (encryption/hash) function with the salt against the entire “dictionary” with the “salt” for each stored password
From OWASP:
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])
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
Never, ever, ever store unencrypted passwords on a server.
You should not use just any encryption algorithm
We will use bcryptjs for class purposes.
bcryptjs
Password Hashingnpm 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
Verificationconst 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}`);
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.
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}'"
}]
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.
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"
}
]