TL;DR
This guide shows you how to securely store passwords using hashing and salting when a user logs in over SSL (HTTPS). This protects your users even if your database is compromised.
What You’ll Need
- A web server with SSL/TLS configured (HTTPS)
- A database to store usernames, passwords (hashed and salted), and salts.
- Server-side programming language (e.g., Python, PHP, Node.js)
Steps
- Understand Hashing & Salting
- Hashing: Converts a password into an irreversible string of characters. You can’t get the original password back from the hash.
- Salting: Adds a random, unique string (the salt) to each password *before* hashing. This makes it much harder for attackers using pre-computed tables of common passwords (rainbow tables).
- Generate Salts
When a new user registers, generate a unique salt for them. A good length is 16-32 random characters.
# Python example using secrets module import secrets salt = secrets.token_hex(16) print(salt) - Store User Data
In your database, store the following for each user:
- Username
- Password Hash (see step 4)
- Salt
- Hash Passwords with Salts
Before storing a password, combine the salt and password, then hash the result. Use a strong hashing algorithm like bcrypt or Argon2.
# Python example using bcrypt import bcrypt password = "mySecretPassword" salt = "someRandomSalt" hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt.encode('utf-8')) print(hashed_password)Important: Store the
hashed_passwordin your database, *not* the original password. - Authentication Process (Login)
- Receive username and password from user.
- Retrieve the salt for that username from the database.
- Combine the entered password with the retrieved salt.
- Hash the combined password + salt using the same hashing algorithm used during registration (e.g., bcrypt).
- Compare the newly generated hash with the stored hash in the database.
- If the hashes match, authentication is successful!
- Example Login Code
# Python example (simplified) import bcrypt def verify_password(entered_password, stored_hash, salt): combined_password = entered_password.encode('utf-8') + salt.encode('utf-8') hashed_password = bcrypt.hashpw(combined_password, salt.encode('utf-8')) return hashed_password == stored_hash.encode('utf-8') - SSL/TLS (HTTPS)
Ensure all login traffic is encrypted using SSL/TLS. This prevents attackers from intercepting usernames and passwords in transit.
- Obtain an SSL certificate for your domain.
- Configure your web server to use HTTPS.
- Redirect HTTP requests to HTTPS.
- Security Considerations
- Strong Hashing Algorithm: Use bcrypt or Argon2 – they are designed to be slow, making brute-force attacks harder.
- Salt Length: Use a salt length of at least 16 characters.
- Unique Salts: Each user *must* have a unique salt.
- Rate Limiting: Limit the number of login attempts to prevent brute-force attacks.
- Regular Updates: Keep your server software and libraries up to date with security patches.