All posts

Hash Generators Explained: MD5 vs SHA-256 vs BCrypt

July 22, 2026 · DevTools

hash
md5
sha256
bcrypt
security
developer-tools

Every Linux download page shows a string like a94a8fe5ccb19ba61c4c0873d391e987982fbbd3... next to the ISO. That string is a hash — a fixed-length fingerprint of the file. If a single bit changes in transit, the hash changes completely, so comparing hashes proves integrity. This guide explains what hash functions do and which algorithm to reach for.

You can generate every hash mentioned here with the Hash Generator — it computes MD5, SHA-1, SHA-256, and SHA-512 entirely in your browser.

What makes a hash function "cryptographic"

A hash function turns any input — three characters or three gigabytes — into a fixed-size digest. Four properties matter:

  1. Deterministic — same input, same output, always
  2. One-way — you can't reconstruct the input from the digest
  3. Avalanche effect — flip one input bit and ~half the output bits change
  4. Collision-resistant — finding two inputs with the same digest is computationally infeasible

That last property is where algorithms age out. Let's look at the lineup.

MD5: fast, but broken

MD5 produces a 128-bit digest (32 hex chars) and it's fast — which is exactly its problem. Researchers have demonstrated practical collision attacks since 2004: attackers can craft two different files with the same MD5 hash.

  • Still fine for: non-adversarial checksums (did this file get corrupted in transit?), cache keys, dedupe identifiers
  • Never use for: signatures, certificates, passwords, anything an attacker might try to fake

SHA-1: deprecated for security

SHA-1 (160-bit) held out longer, but in 2017 Google demonstrated the first real-world collision (the SHAttered attack). Browsers and CAs dropped it, and Git migrated away.

  • Still fine for: legacy compatibility, non-security fingerprinting
  • Never use for: new security designs

SHA-256 & SHA-512: the current standard

The SHA-2 family is what you should default to today:

  • SHA-256 — 256-bit digest (64 hex chars). Used in TLS certificates, Bitcoin, HMAC, and the HS256 algorithm that signs most JWTs.
  • SHA-512 — 512-bit digest. Slightly faster than SHA-256 on 64-bit systems; the extra margin matters in some protocols.

No practical attacks exist against SHA-2. When a spec just says "hash it", this is what it means. (There's also SHA-3 — a completely different construction standardized in 2015 — and BLAKE2, both excellent, but SHA-2 remains the interoperable default.)

Passwords are different: BCrypt

Here's a mistake that never dies: hashing passwords with SHA-256. Fast hashes are a disaster for passwords, because attackers can try billions of guesses per second on a stolen database. And unsalted hashes fall to rainbow tables — precomputed dictionaries of password → hash, so common passwords crack instantly.

Password hashing must be slow on purpose and salted by default:

AlgorithmSpeedSaltPassword-safe?
MD5~billions/secNo
SHA-256~billions/secNo
BCryptconfigurable (e.g., 100 ms)Built-in

BCrypt deliberately burns CPU time (a tunable "cost factor") and generates a random salt automatically, so two users with the same password get different hashes. The resulting string even encodes its own parameters: $2b$12$... means algorithm 2b, cost factor 12 — so verification needs no side data. The BCrypt Generator lets you hash and verify passwords with adjustable cost — useful when testing auth flows.

HMAC: hashes with a key

One more everyday use: HMAC (hash-based message authentication code) combines a hash function with a secret key to prove a message came from someone who knows the key — that's how webhook signatures (GitHub, Stripe) and HS256 JWTs work. A plain hash of secret + message is not safe for this (look up "length extension attack"); HMAC's construction is. Use a library, not string concatenation.

Verifying a checksum in practice

Download pages publish a digest; you hash the file locally and compare:

# macOS / Linux
shasum -a 256 downloaded.iso
# Linux
sha256sum downloaded.iso

Then compare against the published value. Pasting two long hex strings into an editor and squinting is error-prone — the Hash Comparison tool tells you instantly whether two digests match, and can generate the hash from text right there.

A quick sanity test you can run right now

Hash the word hello with SHA-256: you should get 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824. Every correct SHA-256 implementation on Earth produces exactly this digest for this input — that determinism is the whole point. It's a handy way to verify a tool, a library upgrade, or a new environment behaves as expected, and you can check it in seconds with the Hash Generator. Change even one letter — hallo — and the digest flips to something unrecognizably different: d3751d33f9cd5049c4af2b462735457e4d3baf130bcbb87f389e349fbaeb20b9. That total, unpredictable change from a one-bit difference is the avalanche effect in action, and it's the quickest way to see what makes a hash function useful.

Salt vs pepper: the two seasonings

Two terms that get confused:

  • Salt — a random value stored alongside each hash, different per user. It defeats rainbow tables and ensures identical passwords produce different hashes. Not a secret; BCrypt embeds it in the output string automatically.
  • Pepper — a secret value added to every password before hashing, stored separately from the database (e.g., in an environment variable or KMS). If the database leaks but the pepper doesn't, the hashes are useless to the attacker. It's defense-in-depth, not a replacement for a proper password hash.

The password-hashing family: BCrypt, Argon2, scrypt, PBKDF2

BCrypt (1999) is the veteran, but it has siblings worth knowing:

  • Argon2 — the current recommendation (winner of the 2015 Password Hashing Competition). Memory-hard: it demands RAM as well as CPU, which blunts GPU and ASIC attacks.
  • scrypt — also memory-hard; solid, though Argon2 largely superseded it.
  • PBKDF2 — the oldest standardized option (and what many enterprise stacks still mandate). CPU-bound only, so it needs a high iteration count (OWASP suggests 600,000+ for SHA-256) to stay safe.

All four share the same recipe — salt + deliberate slowness — which is the actual lesson: the algorithm matters less than never using a fast general-purpose hash for passwords.

Comparing hashes safely: the timing-attack footnote

When verifying a digest in security code — a webhook signature, a token — don't compare with ==. A naive string comparison returns on the first mismatched character, and measuring those timing differences can reveal the expected value character by character. Use a constant-time comparison (crypto.timingSafeEqual in Node, hmac.compare_digest in Python). For checking whether a downloaded file's checksum matches, the stakes are lower and eyeballing is fine — the Hash Comparison tool exists precisely to make that check instant and error-free.

Quick decision guide

Your taskUse
Verify a download wasn't corruptedMD5 ok, SHA-256 better
File/content fingerprint in a security contextSHA-256
HMAC / JWT signingSHA-256 (HS256)
Storing passwordsBCrypt (or Argon2)
Anything new, unsureSHA-256

Everything stays in your browser

Both generators and the comparison tool run 100% client-side. That matters when the input is a password candidate, a proprietary file, or a token: nothing is transmitted or logged.

Next steps