📝
marcyannotes
  • Welcome
  • Student Guidelines & Policies
    • Student Handbook
    • AI Policy
    • Academic Calendar
  • Environment Setup
    • Local Environment Setup - Mac
    • Local Environment Setup - Windows
    • GitHub Setup
    • Postgres Setup
  • Fullstack Software Engineering Curriculum
    • Overview
    • How-Tos
      • How To Code at Marcy: Code Style Guide
      • How to Do Short Response and Coding Assignments
      • How to Debug
      • How to PEDAC
      • How to Create Projects with Vite
      • How to Deploy on GitHub Pages
      • How to Deploy on Render
    • Mod 0 - Command Line Interfaces, Git, and GitHub
      • Mod 0 Overview
      • Command Line Interfaces
      • Git & GitHub
      • Git Pulling & Merging
      • Git Branching & PRs
      • Pair Programming: BONUS
    • Mod 1 - JavaScriptFundamentals
      • Mod 1 Overview
      • Intro to Programming
      • Errors
      • Node & Node Modules
      • Variables, Functions & String Methods
      • Control Flow, typeof, and Math
      • Loops
      • Arrays
      • Objects
      • Higher Order Functions: Callbacks
      • Higher Order Functions: Array Methods
      • Regex
    • Mod 2 - HTML, CSS & the DOM
      • Mod 2 Overview
      • HTML
      • CSS
      • Accessibility (a11y)
      • The DOM
      • Events
      • Forms
      • The Box Model and Positioning
      • Flexbox
      • Grid & Media Queries
      • ESModules
      • LocalStorage
    • Mod 3 - Async & APIs
      • Mod 3 Overview
      • Promises
      • Fetch
      • Building a Fetching App
      • Async & Await
    • Mod 4 - Project Week!
      • Project Week Overview
    • Mod 5 - Object-Oriented Programming
      • Mod 5 Overview
      • Intro to OOP, Encapsulation, Factory Functions, and Closure
      • Classes
      • Private & Static
      • Has Many/Belongs To
      • Polymorphism
    • Mod 6 - Data Structures & Algorithms
      • Mod 6 Overview
      • Stacks & Queues
      • Nodes & Linked Lists
      • Singly & Doubly Linked Lists
      • Recursion
      • Trees
    • Mod 7 - React
      • Mod 7 Overview
      • Intro to React
      • Events, State, and Forms
      • Fetching with useEffect
      • Building a Flashcards App
      • React Context
      • Global Context Pattern
      • React Router
    • Mod 8 - Backend
      • Mod 8 Overview
      • Intro to Express
      • Building a Static Web Server with Middleware
      • Securing API Keys with Environment Variables
      • Building a RESTful API with MVC
      • SQL and Databases
      • JOIN (Association) SQL Queries
      • Knex
      • Your First Fullstack App!
      • Migrations & Seeds
      • Schema Design & Normalization
      • Hashing Passwords with Bcrypt
  • Code Challenge Curriculum
    • Unit 0
      • Lecture: Functions in JS
      • CC-00: Functions and Console Logs
      • CC-01: Conditionals
      • CC-02: Conditionals 2
    • Unit 1
      • CC-03: For Loops
      • CC-04: For Loops and Conditionals
      • CC-05: For Loops and Conditionals 2
    • Unit 2
      • CC-06: String Mutations
      • CC-07: Array Iteration
      • CC-08: String Mutation and Array Iteration
      • CC-09: Array Mutations
      • CC-10: Reading Objects
      • CC-11: Objects
      • CC-12: Objects
      • Unit 2 Diagnostic
    • Unit 3
      • Intro to PEDAC (and Algorithms)
      • validTime
      • fizzBuzz (array)
      • digitSumDifference
      • firstNotRepeating
      • compareEvenAndOddSum
      • countVowelConsonants
      • finalHP
      • canMakeTriangle
    • Unit 4
    • Unit 5
    • Unit 6
    • Unit 7
    • Unit 8
    • Sorting
Powered by GitBook
On this page
  • Terms
  • Pre-Learning
  • Hashing
  • Verifying Passwords
  • Salting
  • Bcrypt
  1. Fullstack Software Engineering Curriculum
  2. Mod 8 - Backend

Hashing Passwords with Bcrypt

PreviousSchema Design & NormalizationNextCode Challenge Curriculum

Last updated 8 months ago

Follow along with code examples !

Table of Contents:

Terms

  • Hashing - a mathematical algorithm that transforms a string of characters into a fixed-length string of characters.

  • Password Salt - A salt is a random string of data that is added to the input data before the hash function is applied. This changes the hash value that is produced, even for the same input data.

  • Salt Rounds - the number of times a password has been salted before being hashed

  • Plaintext password - the password as it was entered by the user, before it is hashed.

  • Bcrypt - a Node module that provides functions for hashing strings and verifying hashed strings.

Pre-Learning

Check out this video to learn about hashing, salting, and various attacks used by hackers to get accessed to your password!

Hashing

Hashing is a mathematical algorithm that transforms a string of characters into a fixed-length string of characters.

The purpose of password hashing is to prevent attackers who obtain a database of user passwords from easily obtaining the passwords themselves.

  • Without password hashing, an attacker who obtains a user database can simply read the passwords in plain text.

  • With password hashing, the passwords are stored as hash values, and an attacker would need to spend significant time and resources attempting to crack the hash values back into the original passwords.

const hash = (pw) => {
  return convertPasswordToHashedPassword(pw);
}

const users = []; // our "database"

const createNewUser = (username, password) => {
  const hashedPassword = hash(password);
  const user = { username, hashedPassword }
  users.push(user);
}

createNewUser('dogPerson123', 'hElLo')
createNewUser('catsRule678', 'abc')
console.log(users)
// [
//  { username: 'dogPerson123', hashedPassword: 'iFmMp' },
//  { username: 'catsRule678', hashedPassword: 'bcd' }
// ]

Q: What does this hashing function do?

Verifying Passwords

Q: let's say I want to try logging in as user dogPerson123 and I provide the password ihatedogs, how can I verify that the password ihatedogs does or dot not match the hashed password?

The beauty of a hashing function is that it MUST be pure: if given the same plaintext string, it must return the same hashed string every time. We can use this to verify any incoming password attempt:

  • hash the password attempt

  • compare it to the stored hashed password

  • return if they match or not

const hash = (plaintextPassword) => {
  // ...
}

const users = []; // our database

const createNewUser = (username, password) => {
  const hashedPassword = hash(password);
  const user = { username, hashedPassword }
  users.push(user);
}

// take a password attempt and hash it.
// if the same result is produced as the hashed password, its a match!
const authenticate = (passwordAttempt, user) => {
  return hash(passwordAttempt) === user.hashedPassword;
}

createNewUser('dogPerson123', 'hElLo123')
createNewUser('catsRule678', 'abc123')
console.log(users);

authenticate('abc123', users[1]); // true
authenticate('abc1234', users[1]); // false

Salting

A salt is a random string of data that is added to the input data before the hash function is applied. This changes the hash value that is produced, even for the same input data.

Even if two users have the same password, a new salt will be generated and added to the password, generating a unique hash each time.

// A salt is a random string of data that is added to the 
// input data before the hash function is applied. This changes 
// the hash value that is produced, even for the same input data.
const getSalt = () => {
  // this salt is just a random string of 3 letters from alphabet
  let randomSalt = '';
  for (let i = 0; i < 3; i++) {
    randomSalt += alphabet[Math.floor(Math.random() * alphabet.length)];
  }
  return randomSalt;
}

const createNewUser = (username, password) => {
  const salt = getSalt();
  const hashedPassword = hash(salt + password);
  // store the salt along with the hashed password
  // hackers still need 
  const user = { username, hashedPassword, salt };
  users.push(user);
}

const authenticate = (passwordAttempt, user) => {
  // use the salt to hash the password attempt and compare
  return hash(user.salt + passwordAttempt) === user.hashedPassword;
}

Bcrypt

The bcrypt module does this all for us! It has two key methods:

  • bcrypt.hash(password, saltRounds)

  • bcrypt.compare(password, hashedPassword)

const hashPassword = async (password, saltRounds = 8) => {
  try {
    const hashedPassword = await bcrypt.hash(password, saltRounds);
    return hashedPassword;
  } catch (err) {
    return console.error(err.message);
  }
};
const isValidPassword = async (password, hash) => {
  try {
    const isValid = await bcrypt.compare(password, hash);
    return isValid;
  } catch (err) {
    return console.error(err.message);
  }
};

Video: Password Hashing, Salts, Peppers | Explained!
here
Terms
Pre-Learning
Hashing
Verifying Passwords
Salting
Bcrypt
alt text
alt text
alt text