Skip to main content
Authentication Systems Tutorial
CHAPTER 04 Intermediate

Password Hashing and Security

Updated: May 14, 2026
25 min read

# CHAPTER 4

Password Hashing and Security

1. Introduction

If there is only one rule you remember from this entire curriculum, it is this: Never, ever store plain-text passwords in a database. If a hacker breaches your server, or a rogue employee looks at the database, they instantly compromise every user's account. Because users reuse passwords across the internet, exposing their password on your site could allow a hacker to access their bank account. In this chapter, we will explore the science of cryptography, understand the difference between Encryption and Hashing, and learn how to implement modern hashing algorithms like bcrypt.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Differentiate between Encryption (two-way) and Hashing (one-way).
  • Understand the mathematical concept of a Cryptographic Hash Function.
  • Explain the purpose of a "Salt" in defeating Rainbow Table attacks.
  • Implement bcrypt password hashing in PHP, Node.js, and Python.

3. Beginner-Friendly Explanation

Imagine a meat grinder.
  • Encryption (Two-way): You put a secret letter into a magic box. You turn the key, and the letter turns into scrambled nonsense. You can safely mail the box. When your friend receives it, they use their matching key, turn the lock, and the scrambled nonsense turns back into the readable letter. It goes in both directions.
  • Hashing (One-way): You put a prime steak (a password) into a meat grinder and turn the handle. Ground beef comes out the other end. It is physically impossible to turn ground beef back into a prime steak.

Hashing is a one-way mathematical meat grinder. When a user registers, we grind their password and store the "ground beef" in the database. We do not know their real password. When they log in, they give us a steak, we grind it, and check if the new ground beef matches the ground beef stored in the database.

4. Why Not Encryption?

Beginners often ask, "Why don't we just encrypt passwords in the database?" If you encrypt the database, the backend server must possess the "decryption key" to read the passwords. If a hacker breaches your server, they steal the database *and* the decryption key, allowing them to reverse the encryption and steal millions of plain-text passwords. With Hashing, there is no key. Even if the hacker steals the database, they cannot reverse the hashes.

5. What is a Hash Function?

A cryptographic hash function takes an input of any size (e.g., "password123") and outputs a fixed-length string of random characters. Characteristics:
  1. 1. Deterministic: Grinding "password123" will ALWAYS produce the exact same hash: $2y$10$xyz....
  1. 2. Avalanche Effect: Grinding "password124" (changing just one character) produces a completely, radically different hash.
  1. 3. Irreversible: You cannot mathematical calculate the input by looking at the output.

6. The Problem: Rainbow Tables and Salting

If "password123" always hashes to xyz123, a hacker can pre-compute the hashes for every single word in the dictionary, create a massive lookup table (a Rainbow Table), and easily crack simple passwords.

The Solution: Salting. Before the password goes into the meat grinder, the computer generates a completely random string of characters (the Salt), e.g., qR9p. It attaches this to the password: password123qR9p. *Then* it grinds it. Because the salt is randomly generated for every single user, it renders Rainbow Tables mathematically useless. Modern algorithms like bcrypt handle salting automatically.

7. Implementation: PHP (bcrypt)

PHP makes password hashing incredibly easy with native functions. It uses bcrypt by default.
php
123456789101112131415161718
// 1. REGISTRATION: Hashing the password
$rawPassword = "my_secret_password";

// PASSWORD_DEFAULT automatically generates a unique salt and hashes the password
$hashedPassword = password_hash($rawPassword, PASSWORD_DEFAULT);
// Save $hashedPassword to the database
// Example Output: $2y$10$T8ZqYw.t7iO...

// 2. LOGIN: Verifying the password
$userInput = "my_secret_password";
$hashFromDatabase = "$2y$10$T8ZqYw.t7iO..."; // Fetched from SQL

// password_verify extracts the salt from the hash and does the math
if (password_verify($userInput, $hashFromDatabase)) {
    echo "Access Granted!";
} else {
    echo "Access Denied!";
}

8. Implementation: Node.js (bcrypt)

In Node.js, we use the popular bcrypt NPM package.
javascript
123456789101112131415161718192021
const bcrypt = require('bcrypt');

// 1. REGISTRATION
const saltRounds = 10; // Determines how slow/secure the math is
const rawPassword = "my_secret_password";

// Hash the password asynchronously
bcrypt.hash(rawPassword, saltRounds, function(err, hash) {
    // Save 'hash' to the database
});

// 2. LOGIN
const userInput = "my_secret_password";
const hashFromDatabase = "$2b$10$xyz...";

// Compare input to hash
bcrypt.compare(userInput, hashFromDatabase, function(err, result) {
    if (result == true) {
        console.log("Access Granted!");
    }
});

9. Best Practices

  • Algorithm Choice: MD5 and SHA-1 are obsolete and mathematically broken. Never use them for passwords. bcrypt, argon2, and scrypt are the industry standards because they are intentionally designed to be *computationally slow*, making brute-force cracking attempts too expensive for hackers.

10. Common Mistakes

  • Limiting Password Length: Some beginner applications restrict passwords to 15 characters because "the database column is small." This is absurd. Because hash functions *always* output a fixed-length string (e.g., bcrypt always outputs 60 characters), a 5-character password and a 5,000-character password both take exactly 60 characters in the database. Never artificially limit a user's password length.

11. Exercises

  1. 1. Define the difference between Encryption and Hashing. Which mechanism requires a "key" to reverse the process?

12. Coding Challenges

  • Challenge: Using the programming language of your choice (PHP, Node, Python), write a script that takes the string "hello", hashes it using bcrypt, and prints the result. Run the script three times. Notice how the output hash is completely different every single time, even though the input ("hello") is identical? That is the automatic "Salt" in action.

13. MCQs with Answers

Question 1

Why are hashing algorithms like bcrypt and argon2 preferred over MD5 for storing user passwords?

Question 2

What is the cryptographic purpose of "Salting" a password before hashing it?

14. Interview Questions

  • Q: A junior developer suggests using two-way AES-256 encryption for the user password column so that the customer service team can retrieve and read forgotten passwords back to users over the phone. Explain to them why this architecture is a massive security violation.
  • Q: Explain the mechanics of a Rainbow Table attack. How does the implementation of a unique cryptographic "Salt" mathematically defeat this attack vector?

15. FAQs

Q: If the hash function generates a random salt every time, how does the password_verify function know what salt was used to check the password later? A: Algorithms like bcrypt actually store the plain-text salt directly *inside* the final hash string! (e.g., the first 20 characters of the hash are the algorithm ID and the salt). Because the salt is not a secret key, storing it in plain sight is perfectly safe; its only job is to force the hacker to calculate the math uniquely for that specific user.

16. Summary

In Chapter 4, we explored the critical science of password security. We learned that passwords must never be stored in plain text or using reversible encryption. Instead, we use one-way Cryptographic Hash Functions. We examined how "Salts" defeat pre-computed Rainbow Table attacks by injecting randomness into identical passwords. Finally, we demonstrated how to easily implement the industry-standard bcrypt algorithm in multiple backend languages to securely hash during registration and verify during login.

17. Next Chapter Recommendation

Our database is secure, and our login logic is sound. But how does the server "remember" that we logged in when we click to the next page? Proceed to Chapter 5: Sessions and Cookies Authentication.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·