Password Hashing 🔒

Alice and Bob get passwords stolen by a Hacker

TLDR; (too long didn’t read)

Hashing = scrambling passwords so NO ONE can read them! 🔒

  • Hashing is one-way only - you can’t reverse it
  • Same password = same hash every time
  • Even the website owner can’t see your real password!
  • This protects you if hackers steal the database

Background Information

When you create an account on a website, you choose a password. But did you know that good websites never store your actual password?

Instead, they use a special mathematical process called hashing to scramble it into a unique code. This code: - Always looks like random letters and numbers - Can’t be reversed back to your password - Changes completely if even one character in your password changes

Why is this important?

Imagine a hacker breaks into a website’s database: - Bad website (stores passwords): Hacker sees “password123” and can log into your account! - Good website (stores hashes): Hacker sees “ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f” - useless to them!

How does login still work?

When you log in, the website: 1. Takes your password 2. Hashes it the same way 3. Compares the hash to the one they stored 4. If they match - you’re in! ✅


Practical Activity: Password Hashing Detective 🔍

Objective

Explore how password hashing works using Python and discover why it’s a one-way process.

You will need

  • A computer with Python installed
  • The Python code below
  • Paper and pen to record your findings

Step 1: Set up your password hasher

Run this Python code to create your password hashing tool:

Code
import hashlib

def hash_password(password):
    """Hash a password using SHA-256"""
    # Convert password to bytes and hash it
    hashed = hashlib.sha256(password.encode()).hexdigest()
    return hashed

# Test it out!
test_password = "dragon"
hashed_result = hash_password(test_password)

print(f"Password: {test_password}")
print(f"Hash:     {hashed_result}")
print(f"\nHash length: {len(hashed_result)} characters")
Password: dragon
Hash:     a9c43be948c5cabd56ef2bacffb77cdaa5eec49dd5eb0cc4129cf3eda5f0e74c

Hash length: 64 characters

Step 2: Experiment with different passwords

Try hashing different passwords and observe the results:

Code
# Try these passwords
passwords = ["password", "password123", "Password123", "letmein", "qwerty"]

print("PASSWORD HASHING RESULTS")
print("=" * 80)

for pwd in passwords:
    hashed = hash_password(pwd)
    print(f"{pwd:15}{hashed}")
PASSWORD HASHING RESULTS
================================================================================
password        → 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
password123     → ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f
Password123     → 008c70392e3abfbd0fa47bbc2ed96aa99bd49e159727fcba0f2e6abeb3a9d601
letmein         → 1c8bfe8f801d79745c4631d09fff36c82aa37fc4cce4fc946683d7b336b63032
qwerty          → 65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5

Step 3: Investigate the one-way property

Now try to answer these investigation questions by experimenting:

Code
# Investigation 1: What happens with very similar passwords?
print("INVESTIGATION 1: Tiny changes = huge differences")
print("=" * 80)

similar_passwords = ["cat", "Cat", "cats", "cat1"]

for pwd in similar_passwords:
    hashed = hash_password(pwd)
    print(f"{pwd:10}{hashed}")

print("\nNotice: Even changing ONE character completely changes the hash!")
INVESTIGATION 1: Tiny changes = huge differences
================================================================================
cat        → 77af778b51abd4a3c51c5ddd97204a9c3ae614ebccb75a606c3b6865aed6744e
Cat        → 48735c4fae42d1501164976afec76730b9e5fe467f680bdd8daff4bb77674045
cats       → d936608baaacc6b762c14b0c356026fba3b84e77d5b22e86f2fc29d3da09c675
cat1       → 081706ccee3f19f01752ba7b60dec0f901a746fe4e3f8c00b70ee6671669c802

Notice: Even changing ONE character completely changes the hash!
Code
# Investigation 2: Is it consistent?
print("\nINVESTIGATION 2: Same password = same hash?")
print("=" * 80)

password = "elephant"
print(f"Hashing '{password}' five times:\n")

for i in range(1, 6):
    hashed = hash_password(password)
    print(f"  {i}. {hashed}")

print("\nNotice: The same password ALWAYS produces the same hash!")

INVESTIGATION 2: Same password = same hash?
================================================================================
Hashing 'elephant' five times:

  1. cd08c4c4316df20d9c30450fe776dcde4810029e641cde526c5bbffec1f770a3
  2. cd08c4c4316df20d9c30450fe776dcde4810029e641cde526c5bbffec1f770a3
  3. cd08c4c4316df20d9c30450fe776dcde4810029e641cde526c5bbffec1f770a3
  4. cd08c4c4316df20d9c30450fe776dcde4810029e641cde526c5bbffec1f770a3
  5. cd08c4c4316df20d9c30450fe776dcde4810029e641cde526c5bbffec1f770a3

Notice: The same password ALWAYS produces the same hash!
Code
# Investigation 3: Can we reverse it?
print("\nINVESTIGATION 3: Can we go backwards?")
print("=" * 80)

original = "secret"
hashed = hash_password(original)

print(f"Original password: {original}")
print(f"Hashed version:    {hashed}")
print(f"\n❌ There is NO way to reverse this hash back to '{original}'")
print("   Even the website owner cannot see your original password!")

INVESTIGATION 3: Can we go backwards?
================================================================================
Original password: secret
Hashed version:    2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b

❌ There is NO way to reverse this hash back to 'secret'
   Even the website owner cannot see your original password!

Step 4: Test your own passwords!

Important Safety Note: Don’t use your real passwords for practice! Make up fake ones instead.

Code
# Try your own passwords (use FAKE passwords only!)
print("HASH YOUR OWN PASSWORDS")
print("=" * 80)

# Replace these with your own test passwords
my_passwords = [
    "your_test_password_1",
    "your_test_password_2",
    "your_test_password_3"
]

for pwd in my_passwords:
    hashed = hash_password(pwd)
    print(f"{pwd:25}{hashed}")

Discussion Questions

After completing the investigations, discuss these questions:

  1. One-way process: Why is it impossible to reverse a hash back to the original password?

  2. Security: If hackers steal a database of hashed passwords, why can’t they use them to log in?

  3. Consistency: Why is it important that the same password always produces the same hash?

  4. Small changes: What did you notice when you changed just one character in a password? Why is this important?

  5. Real world: Can you think of other situations where one-way hashing might be useful?


Key Takeaways

Hashing is one-way - You can’t reverse it

Consistency matters - Same input = same output (every time)

Tiny changes = huge differences - Changing one character completely changes the hash

Protects your privacy - Even website owners can’t see your real password

Security through mathematics - Hashing uses complex math that’s easy one way, impossible the other


Optional Stretch Activities 🌟

Challenge 1: Password strength explorer

Hash passwords of different lengths. Does a longer password create a longer hash?

Challenge 2: Hash comparison

If someone gives you a hash, can you figure out what their password was by trying common passwords? (This is called a “brute force attack”)

Challenge 3: Encryption vs Hashing

Compare hashing to the encryption lesson you learned earlier: - Which one can be reversed? - When would you use each one? - Why are both important for security?

Challenge 4: Research task

Look up “salt” in password hashing. Why do security experts add salt to passwords before hashing them?