Get a Pentest and security assessment of your IT network.

Cyber Security

Secure Passwords: Server-Side Hashing

TL;DR

This guide shows how to securely store passwords on your server using hashing. We’ll cover why it’s important, the best practices for doing it right, and a simple example.

Why Hash Passwords?

Never store passwords in plain text! If your database is compromised, attackers will have immediate access to all user accounts. Hashing transforms passwords into an irreversible format, protecting them even if the database is stolen.

Steps to Secure Password Storage

  1. Choose a Strong Hashing Algorithm: Use modern algorithms like bcrypt, Argon2, or scrypt. These are designed to be slow and computationally expensive, making brute-force attacks harder.
    • bcrypt: A widely used and well-tested algorithm.
    • Argon2: A newer algorithm offering better security against GPU cracking.
    • scrypt: Another strong option but less common than bcrypt or Argon2.
  2. Salt Your Passwords: A salt is a random string added to each password before hashing. This prevents attackers from using pre-computed tables of hashes (rainbow tables).
    • Each user should have a unique salt.
    • Store the salt alongside the hashed password in your database.
  3. Implement Password Hashing on Server-Side: Perform all hashing operations on your server, never on the client-side.

    Here’s a Python example using bcrypt:

    import bcrypt
    
    def hash_password(password):
      salt = bcrypt.gensalt()
      hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
      return hashed_password.decode('utf-8')
    
    def verify_password(password, hashed_password):
      return bcrypt.checkpw(password.encode('utf-8'), hashed_password.encode('utf-8'))
    
  4. Store Salts and Hashes Securely: Protect your database from unauthorized access.
    • Use strong database passwords.
    • Restrict database access to only necessary users and applications.
    • Regularly back up your database.
  5. Password Verification: When a user logs in, hash the entered password with their stored salt and compare it to the stored hash.

    Using the Python example above:

    user_password = "mysecretpassword"
    stored_hash = "$2b$12$EXAMPLEHASHEDPASSWORD"
    
    if verify_password(user_password, stored_hash):
      print("Password verified!")
    else:
      print("Incorrect password.")
    
  6. Regularly Re-Hash Passwords: As hashing algorithms evolve and computing power increases, consider periodically re-hashing passwords with a stronger algorithm or longer salt lengths.
  7. Rate Limiting: Implement rate limiting on login attempts to prevent brute-force attacks.
    • Limit the number of failed login attempts per IP address within a specific timeframe.

Important Considerations

  • Never roll your own cryptography: Use well-established libraries and algorithms.
  • Keep libraries updated: Security vulnerabilities are often discovered in cryptographic libraries, so keep them up to date.
  • Consider multi-factor authentication (MFA): Adding MFA provides an extra layer of security beyond passwords.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation