How to Generate Secure Hashes for Password Storage
Learn password hashing best practices using SHA-256, salt, and pepper. Protect user passwords with industry-standard cryptographic techniques.
Storing passwords securely is one of the most critical responsibilities for any developer. Never store plain-text passwords. This guide covers modern password hashing techniques using salt, pepper, and strong algorithms.
What is This?
Password hashing converts a password into a fixed-length string using a one-way cryptographic function. Unlike encryption (which is reversible), hashing is designed to be irreversible. Even if an attacker steals your database, they cannot recover the original passwords from secure hashes.
Best Practices for Password Hashing
- Choose a strong algorithm (bcrypt, Argon2, or PBKDF2 - NOT MD5 or basic SHA-1)
- Generate a unique random salt for each password (16+ bytes)
- Combine the password with the salt before hashing
- Store both the hash and salt in your database (salt is not secret)
- Add a pepper (secret key) stored separately from database for additional security
- Use multiple iterations (work factor) to slow down brute-force attacks
Benefits
- User Protection: Users' passwords remain safe even if database is breached
- Rainbow Table Defense: Salt prevents precomputed hash attacks
- Compliance: Meet security standards like GDPR, HIPAA, PCI-DSS
- Reputation: Avoid data breach scandals and loss of user trust
- Legal Protection: Demonstrate due diligence in protecting user data
Common Use Cases
User Registration
When users create accounts, hash their passwords with bcrypt (work factor 10-12) before storing. Generate a unique salt for each user. Store hash and salt in database, but NEVER store the original password.
Password Verification
During login, retrieve the stored hash and salt. Hash the submitted password with the same salt, then compare the results. If hashes match, password is correct. Never compare plain-text passwords.
Password Reset
When users reset passwords, generate a new salt and hash. Never "decrypt" the old password (it's impossible with proper hashing). Always create a new hash with a new salt for the new password.
Legacy Migration
Migrating from insecure storage (plain-text or MD5)? Force password resets on next login, then hash with bcrypt. Or rehash during login: verify old hash, then save new bcrypt hash for future logins.
Tips & Tricks
- Never use MD5 or SHA-1 alone: These are too fast and vulnerable to rainbow tables
- Use bcrypt, Argon2, or PBKDF2: These are designed specifically for password hashing
- Unique salt per password: Never reuse salts across multiple passwords
- Store salt with hash: Salt doesn't need to be secret - it just prevents rainbow tables
- Add pepper for extra security: Store a secret pepper key outside database (environment variable)
- Use work factor/iterations: Slow down brute-force attacks with bcrypt cost factor 10-12
- Consider Argon2: Winner of Password Hashing Competition, resistant to GPU attacks
Conclusion
Secure password hashing is non-negotiable for modern web applications. Using strong algorithms like bcrypt with unique salts protects users even when databases are compromised. Never implement your own crypto - use vetted libraries like bcrypt.js, argon2, or native platform APIs. Remember: SHA-256 alone is NOT sufficient for password hashing. Use our hash generator to learn about different algorithms, but implement proper password hashing in your production code with bcrypt or Argon2.