TL;DR
If your password hashing takes less than 1000 milliseconds (1 second) on your server, Argon2 is likely slower and potentially less secure than bcrypt. Stick with bcrypt in this case. For longer runtimes, Argon2 offers better security.
Understanding the Problem
Argon2 is a modern password hashing algorithm designed to be more resistant to attacks like GPU cracking than older algorithms like bcrypt. However, it’s more complex and requires careful configuration. A key factor in its security is runtime – how long it takes to hash a password. If Argon2 doesn’t run for a sufficient amount of time (generally considered at least 1000ms), it doesn’t get the chance to fully utilise its memory-hard properties, reducing its effectiveness.
Solution: Check & Adjust Your Password Hashing
- Test Your Current Implementation’s Runtime
- You need to measure how long it takes your system to hash a password using your current settings. The exact method depends on the language/framework you’re using. Here are examples:
- Python (using
bcrypt):import time import bcrypt password = b"supersecretpassword" start_time = time.time() hashed = bcrypt.hashpw(password, bcrypt.gensalt()) end_time = time.time() runtime = end_time - start_time print(f"bcrypt runtime: {runtime:.4f} seconds") - PHP (using
password_hash):$password = 'supersecretpassword'; $start_time = microtime(true); $hashed = password_hash($password, PASSWORD_BCRYPT); $end_time = microtime(true); $runtime = $end_time - $start_time; echo "bcrypt runtime: " . $runtime . " seconds";
- Python (using
- If Runtime is < 1000ms (1 Second)
- Stick with bcrypt. Don’t switch to Argon2 unless you can increase the runtime significantly.
- Consider increasing bcrypt’s cost factor. This makes it slower and more secure, but also increases server load. Test thoroughly!
# Example (Python): hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12)) # Increase rounds - If Runtime is > 1000ms
- Argon2 is a good choice. Configure it appropriately.
- Memory Cost (t): The amount of memory Argon2 uses. Higher is better, but requires more resources.
- Iterations (m): The number of passes through the data. Higher is better.
- Parallelism (p): The number of parallel threads used. Usually set to 1 or 2.
- Example Argon2 Configuration (Python using
argon2-cffi):import argon2 password = b"supersecretpassword" hash_format = argon2.PasswordHasher(time_cost=2, memory_cost=64 * 1024, parallelism=2, hash_len=32) hashed = hash_format.hash(password) - Regularly Re-evaluate
- Server hardware changes (faster CPUs, more memory) can affect runtime. Periodically re-test your hashing speed and adjust settings as needed.
Important Considerations
- Salt Length: Always use a unique salt for each password. Both bcrypt and Argon2 handle this automatically with their default functions.
- Storage: Store the hashed passwords securely (e.g., using a database designed for security).
- Library Choice: Use well-maintained, reputable libraries for both bcrypt and Argon2.

