Blog | G5 Cyber Security

Password Hashing: Why Double Hashing is Weak

TL;DR

Hashing a hash of your password doesn’t make it more secure – in fact, it makes it less secure. It provides no real benefit and introduces potential vulnerabilities. Use a strong, modern key derivation function (KDF) like Argon2id or bcrypt instead.

Why Double Hashing is Bad

The idea behind hashing a hash of a password seems logical at first: add another layer of protection. However, it’s fundamentally flawed and doesn’t achieve the intended security goals. Here’s why:

Step-by-Step Solution: Replace Double Hashing

  1. Understand Key Derivation Functions (KDFs): KDFs are specifically designed for password hashing. They take a password and salt as input and produce a strong, fixed-size hash that is computationally expensive to compute.
  2. Choose a Strong KDF:
    • Argon2id: Generally considered the most secure option. It’s resistant to GPU cracking and side-channel attacks.
    • bcrypt: A well-established and widely used KDF.
    • scrypt: Another good option, but Argon2id is preferred.
  3. Implement the Chosen KDF: Use a library in your programming language to implement the KDF correctly. Do not attempt to write your own hashing algorithm!

Example using Python and Argon2id

This example uses the argon2-cffi library. You’ll need to install it first: pip install argon2-cffi.

import argon2

pw = "mysecretpassword"
salt = argon2.generate_salt()
hash = argon2.hash(pw, salt=salt)

print("Hash:", hash)

# Verify the password
try:
    argon2.verify(hash, pw)
    print("Password verified!")
except argon2.exceptions.VerifyError:
    print("Incorrect password.")

Example using PHP and bcrypt

PHP’s password_hash() and password_verify() functions provide a simple way to use bcrypt.

<?php
$password = "mysecretpassword";
$hash = password_hash($password, PASSWORD_BCRYPT);

if (password_verify("mysecretpassword", $hash)) {
    echo "Password verified!";
} else {
    echo "Incorrect password.";
}
?>

Step 3: Store the Salt with the Hash

The salt is crucial for security. Always store it alongside the hash in your database. The Argon2id example above demonstrates this.

Step 4: Update Existing Passwords (Important!)

  1. Iterate through all user accounts.
  2. Retrieve each password and its current salt (if any).
  3. Re-hash the password using the chosen KDF with a new, randomly generated salt.
  4. Update the database with the new hash and salt.

This is a critical step to ensure all passwords are protected by the stronger hashing algorithm.

Step 5: Configuration

Configure your KDF appropriately. Argon2id has parameters for memory cost, time cost and parallelism. Increase these values (within reasonable limits) to increase the computational effort required for cracking. bcrypt also has a cost parameter; higher costs are more secure but slower.

cyber security Best Practices

Exit mobile version