Bcrypt and Argon2 for Password Hashing — Why MD5 Is Dead and How to Choose the Best Algorithm
> cd .. / HUB_EDITORIALE
Sicurezza Informatica

Bcrypt and Argon2 for Password Hashing — Why MD5 Is Dead and How to Choose the Best Algorithm

[2026-07-17] Author: Ing. Calogero Bono
> share
Zenithby Meteora Web The operating system for your business. Social, clients, bookings and invoices in one platform. Gyms, barbers, professionals. Discover Zenith Free demo · no card

If you manage a web application with registered users, you already know that passwords must never be stored in plain text. But you might not know that MD5 is not only insecure — it's been dead for years. Yet we still see it in legacy projects: passwords hashed with MD5, SHA1, sometimes without any salt. At Meteora Web, whenever we see a database like that, we treat it as an open vulnerability. An attacker with an old GPU cluster can invert MD5 at billions of hashes per second. You don't need to be a super-hacker like the ones from GPT-Red to crack it.

In this guide, we'll dive into why MD5 and SHA1 must be retired, how bcrypt and Argon2 work, and how to implement them in PHP (the concepts apply to any language). Let's start with the concrete problem: why your authentication system might be a ticking time bomb.

Why MD5 and SHA1 Are No Longer Safe for Passwords

MD5 was designed as a fast hash for file integrity, not for credential security. Its speed is the problem: today a single PC with a GPU can perform millions of attempts per second. With rainbow tables and dictionary attacks, a weak password like “password123” is cracked in milliseconds. Even with a salt, the fast computation makes brute-force feasible. SHA1 is in the same boat. The real issue is that good password hashing must be deliberately slow and resource-intensive to slow down brute-force attacks.

Sponsored Protocol

We see it in projects that come to us: a client asks us to migrate from an old CMS with MD5 passwords to a modern system. The first step? Force all users to reset their passwords, because the old hashes cannot be securely converted. That's why MD5 is dead — no patch can make it suitable for passwords.

The failure of MD5 and SHA1 in numbers

An MD5 hash is computed in about 0.5 microseconds on modern hardware. With an 8-GPU cluster, an attacker can try over 100 billion hashes per second. An 8-character alphanumeric password is exhausted in minutes. Argon2id, with appropriate parameters, takes about 1 second per hash. The same attack becomes impractical. The numbers speak for themselves.

What Makes Bcrypt and Argon2 Different? Why Are They Safer?

Bcrypt and Argon2 are key derivation functions designed specifically for passwords. They have three fundamental features:

  • Built-in slowness: computational cost is adjustable via cost parameters (cost factor for bcrypt, memory cost and parallelism for Argon2).
  • Automatic salting: each hash includes a random salt, making precomputed table attacks impossible.
  • Hardware resistance: Argon2 is designed to resist GPU, FPGA, and ASIC attacks because it requires a significant amount of memory.

Bcrypt uses the Blowfish cipher and a cost factor that controls the number of iterations. Argon2 is the winner of the 2015 Password Hashing Competition (PHC) and has three variants: Argon2d (side-channel resistant), Argon2i (timing attack resistant), and Argon2id (combination, recommended).

Sponsored Protocol

How Bcrypt Manages Cost Compared to Argon2?

In bcrypt, the cost is an exponential value (2^cost). Setting cost=10 means 2^10=1024 iterations. Increasing cost by 1 doubles the execution time. Argon2, on the other hand, has three parameters: time (t), memory (m), and parallelism (p). You can balance speed and memory consumption. For modern applications, OWASP and NIST recommend Argon2id.

How to Implement Bcrypt and Argon2 in PHP for Your Application

PHP provides native functions through the password_hash library. No extra extensions needed (bcrypt is supported since PHP 5.5+, Argon2 since PHP 7.2+ with libsodium).

Practical example: password_hash with bcrypt

The simplest and most secure way to generate a password hash in PHP:

// Hash with bcrypt (cost 12)
$hash = password_hash('MyPassword!123', PASSWORD_BCRYPT, ['cost' => 12]);
echo $hash; // $2y$12$...

// Verify
if (password_verify('MyPassword!123', $hash)) {
    echo 'Password correct';
}

Why cost=12? On a modern server, 12 is a good compromise between security and performance (about 0.1-0.5 seconds). On our PHP hosting stack, we always test execution time. If the server is slow, we lower to 10, but never below 8.

Sponsored Protocol

Practical example: password_hash with Argon2id

Argon2id requires memory and time parameters. Here's an example for PHP 8+ with reasonable values:

// Hash with Argon2id
$options = [
    'memory_cost' => 1<<17, // 128 MB
    'time_cost'   => 4,     // 4 iterations
    'threads'     => 2,     // parallelism
];
$hash = password_hash('MyPassword!123', PASSWORD_ARGON2ID, $options);

// Verify: same password_verify function
if (password_verify('MyPassword!123', $hash)) {
    echo 'Password verified with Argon2id';
}

Attention: Argon2 consumes a lot of RAM. If your server has limited memory (e.g., a 1GB VPS), reduce the memory_cost. For shared hosting, bcrypt is often more practical. We recommend testing on your specific environment.

Why not do manual hashing?

Many developers attempt to write their own hashing function or manually concatenate a salt. Don't do it. The native functions like password_hash and password_verify already handle salting, cost, and future upgrades. We've seen it in various projects: someone implemented a custom system with MD5 + random salt thinking it was safe, but it was still vulnerable to speed.

Sponsored Protocol

Argon2 vs Bcrypt: Which One to Choose for Your Project?

The short answer: Argon2id is technically superior, but bcrypt is still a solid and more compatible choice. Here's a practical comparison:

FeatureBcryptArgon2id
GPU resistanceGood (high cost factor)Excellent (memory hard)
Memory consumptionLow (~4KB)Configurable (typically 64-128 MB)
Adjustable speedYes (cost factor)Yes (time, memory, parallelism)
PHP support5.5+ (native)7.2+ (with libsodium)
OWASP recommendationYes (cost >=10)Yes (Argon2id)

At Meteora Web, we use Argon2id on new projects if the server supports it, otherwise bcrypt with cost 12. Never use MD5, SHA1, SHA256, or SHA512 for passwords — even with salt, they are too fast.

How to Migrate Existing Passwords from MD5 to Bcrypt or Argon2

Migration is not trivial: you cannot convert an MD5 hash to a bcrypt hash without knowing the original password. The standard strategy is:

  1. On login, verify the old password (MD5) and if correct, regenerate the hash with bcrypt/Argon2 and update the database.
  2. Set a flag in the database to distinguish old and new hashes.
  3. After a transition period (e.g., 6 months), force a password reset for accounts still using old hashes.

Example logic in PHP:

function verifyAndUpgrade($password, $storedHash, $userId) {
    // Already modern algorithm
    if (password_verify($password, $storedHash)) {
        // Optional: rehash if cost needs increase
        if (password_needs_rehash($storedHash, PASSWORD_BCRYPT, ['cost' => 12])) {
            updateUserHash($userId, password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]));
        }
        return true;
    }
    // Legacy MD5
    if (md5($password) === $storedHash) {
        $newHash = password_hash($password, PASSWORD_ARGON2ID);
        updateUserHash($userId, $newHash);
        return true;
    }
    return false;
}

What to Do Now

Don't leave password security to chance. Here are three immediate actions for your application:

Sponsored Protocol

  1. Check your database: if you see fixed-length hash columns (32 chars for MD5, 40 for SHA1), you have a problem. Plan migration.
  2. Update your code: use password_hash() with PASSWORD_ARGON2ID or PASSWORD_BCRYPT. Set a cost that takes at least 0.2 seconds on your server.
  3. Train your team: explain why MD5 is dead and how to recognize it. If you've been following companies since 2017, you know this kind of error repeats often.

For a deeper dive into the entire cryptography ecosystem for security, read our Pillar Guide to Cryptography and Data Security.

> share
Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere informatico, fondatore di Meteora Web e Zenith OS. System administrator e progettista di piattaforme, app e CMS proprietari, con esperienza in sviluppo full-stack, marketing digitale ed ecosistema Google.
[ Read Full Dossier ]

> METEORA_WEB // DIGITAL AGENCY

We build the digital presence your business deserves.

Websites, social media, online advertising, e-commerce and high-performance hosting, engineered with method by computer engineers in Sciacca, for all of Italy.

> MW_JOURNAL

> READ_ALL()