Bcrypt vs Argon2
In-Depth Technical Comparison & Architecture Guide
Stashing passwords safely requires a special class of cryptographic functions: slow, resource-intensive hashing algorithms. Unlike fast, general-purpose hashes like MD5, SHA-1, or SHA-256 (which are designed to process megabytes of file data in milliseconds), password hashing algorithms are intentionally throttled to delay brute-force cracking attempts. For over two decades, Bcrypt has been the standard recommendation for securing user databases. However, the emergence of Argon2—the winner of the Password Hashing Competition (PHC)—has changed the security landscape. This guide compares Bcrypt and Argon2 across algorithm safety, hardware resistance, and configuration details.
Quick Reference Matrix
| Feature | Bcrypt | Argon2 (Argon2id) |
|---|---|---|
| Year Released | 1999 | 2015 |
| Primary Resource | CPU bound (computationally heavy) | Memory and CPU bound (memory-hard) |
| GPU Crack Resistance | Moderate (vulnerable to parallel loops) | High (throttled by memory bandwidth) |
| ASIC Crack Resistance | Low (ASICs easily outpace CPUs) | High (extremely expensive to build memory-rich ASICs) |
| Tuning Parameters | 1: Cost Factor (rounds) | 3: Memory ($m$), Time ($t$), Parallelism ($p$) |
| Max Password Length | Strictly 72 bytes (truncates extra) | No practical limit (up to 4 GB) |
| Standards Status | De facto standard, legacy support | PHC Winner (2015), RFC 9106 default |
| Standard Salt Size | 128 bits (16 bytes) | 128 bits (16 bytes) default, customizable |
Technology Overview
Bcrypt was designed in 1999 by Niels Provos and David Mazières, based on the Blowfish symmetric block cipher. It introduces an iterative work factor that exponentially increases CPU cycles required to compute a hash. By adjusting this cost, developers can ensure that verification remains fast for legitimate logins (e.g. 100-200ms) while raising the cost of brute-forcing database leaks to astronomical heights.
Argon2 was released in 2015, specifically designed to address Bcrypt's modern weakness: hardware acceleration. While Bcrypt is CPU-bound and uses very little memory, Argon2 introduces "memory hardness." It requires both CPU cycles and large, configurable allocations of RAM to complete a hash. This memory requirement prevents attackers from deploying massive, highly parallel GPU or ASIC (Application-Specific Integrated Circuit) arrays to crack passwords cheaply.
GPU and ASIC Cracking: Why Bcrypt is Vulnerable
Bcrypt relies almost exclusively on CPU computational throughput. Its memory usage is minimal, requiring only about 4 KiB of cache space to run the Blowfish cipher tables. While this was safe in 1999, modern graphics cards (GPUs) contain thousands of small parallel processors designed to handle floating-point math and simple memory access in parallel.
An attacker who obtains a database of bcrypt hashes can offload the cracking process to custom GPU setups or specialized ASIC chips. Because bcrypt has a tiny memory footprint, the attacker can run thousands of bcrypt operations simultaneously on a single GPU. Argon2 eliminates this hardware advantage by incorporating massive memory-hard operations. To compute an Argon2 hash, the parser must read and write from a large memory buffer (often 16 MiB to 64 MiB). This memory requirement saturates the GPU's memory bus, reducing its parallel execution capability and neutralizing the attacker's hardware acceleration advantage.
Brute-force Cracking Resistance:
- Bcrypt: Uses ~4 KiB RAM. GPUs can execute thousands of hashing tasks in parallel.
- Argon2: Uses customizable RAM (e.g., 64 MiB). GPUs are severely throttled by memory bus bottlenecks.Memory footprint comparison and its impact on parallel cracking speeds.
Argon2 Variants: Argon2i, Argon2d, and Argon2id
Argon2 is implemented in three distinct variants, each optimized for different security environments:
1. **Argon2i**: This variant uses data-independent memory access. The order in which memory locations are read and written is pre-determined and does not depend on the input password. This makes it highly resistant to side-channel timing attacks, which attempt to steal cryptographic keys by measuring memory latency. It is the recommended choice for password hashing in environments where timing channels are a major concern.
2. **Argon2d**: This variant uses data-dependent memory access. The sequence of memory reads is dictated by the input password. This makes it extremely resistant to GPU/ASIC cracking arrays because the memory access pattern cannot be pre-computed. However, it is theoretically vulnerable to side-channel timing attacks if an attacker has low-level hardware access to the system.
3. **Argon2id**: This is a hybrid variant. It acts as Argon2i for the first pass over memory (securing the process against timing attacks) and as Argon2d for subsequent passes (securing against GPU acceleration). Argon2id is widely recognized by cryptographers and security standards (including RFC 9106) as the default recommended variant for general password storage.
The 72-Byte Password Limit in Bcrypt
One major architectural quirk of Bcrypt is its password length limit. Bcrypt silently truncates any input password longer than 72 bytes (characters). If a user inputs a 100-character passphrase, Bcrypt only hashes the first 72 characters and ignores the remaining 28.
This creates a security risk: if an attacker knows a user has a long passphrase, they only need to brute-force the first 72 characters to gain access. Furthermore, if the user changes characters at the end of their long passphrase (beyond the 72nd byte), the resulting hash is identical. Argon2 has no such limit; it can process passphrases up to 4 GiB, making it fully compatible with extremely long passphrases and security key exchanges.
// Bcrypt 72-byte truncation behavior
import bcrypt from 'bcryptjs';
const pass1 = "a".repeat(72) + "SECRET_TAIL";
const pass2 = "a".repeat(72) + "DIFFERENT_TAIL";
const hash1 = bcrypt.hashSync(pass1, 10);
const hash2 = bcrypt.hashSync(pass2, 10);
// Both compare to TRUE because the tail is ignored by bcrypt!
console.log(bcrypt.compareSync(pass2, hash1)); // true
console.log(hash1 === hash2); // false (due to random salt, but they validate the same)Demonstration of Bcrypt's silent 72-byte truncation behavior in Node.js.
Configuration, Cost Factors, and Tuning Parameters
Bcrypt is simple to configure because it only has one tuning parameter: the Cost Factor (or logarithmic rounds). A cost factor of 10 means $2^{10} = 1024$ rounds of encryption. Adjusting this parameter scales the computation time exponentially.
Argon2 offers three separate tuning dimensions to match your exact hardware profile: Memory Cost ($m$, the size of the RAM array in KiB), Time Cost ($t$, the number of execution iterations), and Parallelism ($p$, the number of threads utilized). While this makes Argon2 more complex to configure, it allows you to optimize memory usage to maximize GPU cracking costs without overloading your server CPU.
Bcrypt Advantages & Disadvantages
Advantages / Pros
- Extremely mature, battle-tested standard with over 20 years of active security validation.
- Simple implementation with only one parameter (cost factor) to manage and adjust.
- Excellent library support across all languages and framework boilerplates.
Disadvantages / Cons
- Silent truncation of passwords longer than 72 bytes limits the use of massive passphrases.
- CPU-only constraint makes hashes vulnerable to accelerated GPU and ASIC cracking machines.
- Lack of configuration parameters prevents tuning to exploit multi-threaded server hardware.
Argon2id Advantages & Disadvantages
Advantages / Pros
- Advanced memory hardness prevents brute-force acceleration on GPUs and ASICs.
- Hybrid structure protects against both side-channel timing attacks and parallel hardware cracking.
- No password length limitations, accommodating long passphrases and passkeys.
- Highly customizable parameters allow fine-tuning for specific server memory and thread architectures.
Disadvantages / Cons
- More complex to configure correctly; bad tuning parameters can crash servers or make logins slow.
- Requires allocating RAM per login attempt, which can expose servers to Denial of Service (DoS) attacks if not managed.
- Native binary dependencies (node-argon2) can be trickier to compile in some CI/CD environments than pure JS bcrypt wrappers.
Real-World Use Cases
Bcrypt
Legacy Enterprise Systems
Maintaining compatibility in existing user databases that have leveraged bcrypt authentication schemas for years.
Simple Web Applications
Securing user passwords in projects where absolute protection against ASIC rigs is not the primary risk vector, or where simple server setups cannot handle large RAM allocations.
Argon2id
Modern Authentication Backends
Building new user databases and identity providers where security and resilience against modern GPU cracking are primary requirements.
High-Value Security Services
Hashing master keys, financial transaction credentials, and cryptographic seed phrases that require extreme security thresholds.
Developer Recommendation
For all new greenfield applications, choose Argon2id. It is the modern industry standard, recommended by OWASP, the PHC panel, and RFC 9106. Set the parameters to at least 15 MiB of RAM ($m=15360$), 2 iterations ($t=2$), and 1 thread ($p=1$) as a baseline, tuning higher if server resources allow.
Use Bcrypt only if you are working on a legacy system, or if your application environment lacks access to native C bindings for Argon2 and requires a pure JavaScript hashing implementation.
Pro Tip: If you must use Bcrypt, pre-hash passwords using SHA-256 before feeding them to Bcrypt. This solves the 72-byte limit (since SHA-256 digests are always 32 bytes/64 hex characters) while retaining bcrypt's computational work factor.
Frequently Asked Questions
- Why is Argon2 better than Bcrypt?
- Argon2 is better because it is a memory-hard algorithm. It requires a customizable amount of RAM to run, which prevents attackers from using parallel GPU hardware arrays to speed up cracking attempts. Bcrypt uses very little RAM, making it vulnerable to GPU cracking.
- What happens if a password is longer than 72 characters in Bcrypt?
- Bcrypt silently truncates passwords longer than 72 bytes. This means it ignores any characters beyond the 72nd character, which can lead to situations where different passwords hash to the exact same value.
- Which Argon2 variant should I use for passwords?
- Use Argon2id. It combines data-independent and data-dependent memory access, making it highly secure against timing attacks while protecting against GPU-accelerated cracking.
- Does Argon2 require a lot of server memory?
- Yes, but you can configure the memory requirement. Standard settings allocate between 16 MiB and 64 MiB of memory per hash. You must tune this to match your server's capacity and avoid Out of Memory (OOM) errors during traffic spikes.
- Can I migrate from Bcrypt to Argon2?
- Yes. You can transition by verifying the user's password using Bcrypt during their next login, and then immediately rehashing and saving their password using Argon2id.
- Does ScriptPulse.tools support Bcrypt generation?
- Yes. You can generate and test Bcrypt hashes in your browser using the Bcrypt Hasher tool on ScriptPulse.tools. Hashing happens locally in your browser.
Launch Interactive Developer Tools
Put these concepts into practice. Test, format, serialize, or analyze your inputs locally with these secure, browser-only utilities: