Common Salting Mistakes and Misconceptions
Common Salting Mistakes and Misconceptions
Global salts, where one salt is used for all passwords, provide minimal security improvement. While they prevent using pre-existing rainbow tables, attackers can generate a custom rainbow table for the specific salt after obtaining it. This approach is sometimes called "peppering" when the global value is kept secret, but it shouldn't be confused with proper per-password salting.
Salt reuse across password changes creates vulnerabilities. When users change passwords, generate new salts even if the old salt could be reused. Salt reuse might allow attackers to determine if a user chose their previous password again or identify password patterns. Always treat password changes as completely new password creation events.
def common_salting_mistakes():
"""Demonstrate common salting implementation errors"""
print("Common Salting Mistakes:\n")
# Mistake 1: Global salt
GLOBAL_SALT = b"ThisIsAGlobalSalt" # BAD!
passwords = ["password123", "admin", "letmein"]
print("❌ Mistake 1: Using global salt")
for pwd in passwords:
bad_hash = hashlib.sha256(GLOBAL_SALT + pwd.encode()).hexdigest()
print(f" {pwd}: {bad_hash}")
print(" Problem: Attacker can build rainbow table for this salt!\n")
# Mistake 2: Short salts
print("❌ Mistake 2: Using short salts")
for pwd in passwords:
short_salt = secrets.token_bytes(4) # Only 4 bytes!
bad_hash = hashlib.sha256(short_salt + pwd.encode()).hexdigest()
print(f" {pwd}: Salt={short_salt.hex()} (only 2^32 possibilities!)")
print(" Problem: Feasible to generate rainbow tables for all salts!\n")
# Mistake 3: Predictable salt generation
print("❌ Mistake 3: Predictable salt generation")
for i, pwd in enumerate(passwords):
# Using user ID as salt - predictable!
bad_salt = f"user_{i}".encode()
bad_hash = hashlib.sha256(bad_salt + pwd.encode()).hexdigest()
print(f" User {i}: Salt='{bad_salt.decode()}' - Predictable!")
print(" Problem: Attackers can predict salts without database access!\n")
# Mistake 4: Salt-hash separation
print("❌ Mistake 4: Storing salt and hash separately")
print(" Users table: id, username, password_hash")
print(" Salts table: user_id, salt")
print(" Problem: Increases complexity and chance of salt loss!")
common_salting_mistakes()