Blog | G5 Cyber Security

Client-Side Password Hashing: Extra Security

TL;DR

Adding client-side password hashing (like using a JavaScript library to hash the password in the browser before sending it to your server) is an extra layer of security on top of standard practices like HTTPS and server-side hashing. It doesn’t replace those, but makes things harder for attackers if your server gets compromised.

Why Add Client-Side Hashing?

You already have good security in place, right? HTTPS protects data in transit, and you hash passwords on the server before storing them. That’s great! But what happens if an attacker does manage to get into your database?

Client-side hashing adds a hurdle for attackers by making stolen hashes less useful.

How Client-Side Hashing Works

  1. Hashing in the Browser: Use a JavaScript library (like bcrypt.js, scrypt.js or argon2-browser) to hash the password directly in the user’s browser before it’s sent to your server.
  2. Salt Generation: Generate a unique salt for each password on the client side. This is crucial!
  3. Send Hash & Salt: Send the hashed password and the salt to your server.
  4. Server Storage: Store both the hash and the salt in your database, associated with the user account.
  5. Authentication: When a user logs in:
    • Hash the entered password using the stored salt for that user (on the server).
    • Compare the new hash to the stored hash.

Step-by-Step Implementation

  1. Choose a Library: Select a suitable JavaScript hashing library. Consider factors like algorithm strength, browser compatibility and maintenance.
    npm install bcryptjs
  2. Generate Salt on Client Side: Use the library to generate a random salt for each user during registration or password change.
    const salt = await bcrypt.genSalt(10); // 10 is the cost factor (higher = slower, more secure)
  3. Hash Password on Client Side: Hash the password using the generated salt before sending it to the server.
    const hash = await bcrypt.hash(password, salt);
  4. Send Hash and Salt to Server: Send both the hash and the salt to your backend.
  5. Store Hash and Salt in Database: Store these values securely associated with the user’s account.
  6. Verification on Login: When a user attempts to log in:
    • Retrieve the stored hash and salt from the database for that user.
    • Hash the entered password using the retrieved salt (on the server).
    • Compare the newly generated hash with the stored hash.
      const match = await bcrypt.compare(enteredPassword, storedHash); // Returns true if passwords match

Important Considerations

Exit mobile version