Utilo

MD5 vs SHA-256: Differences, Security and When to Use Each

Compare MD5, SHA-1, SHA-256 and SHA-3: how hash functions work, why MD5 is broken, speed, checksums, HMAC and the right way to hash passwords.

· 6 min read

Hash functions are among the most widely used building blocks in software. They verify downloads, deduplicate files, sign API requests, power Git and blockchains, and protect stored passwords. MD5 and SHA-256 are the two names developers encounter most often, and the question "can I still use MD5?" comes up constantly. The short answer: for anything involving security, no; for detecting accidental corruption, it still works. The longer answer explains why, and what to use instead.

What a cryptographic hash function does

A hash function takes input of any length and produces a fixed-length output called a digest. MD5 produces 128 bits (32 hex characters); SHA-256 produces 256 bits (64 hex characters).

MD5("hello world")     = 5eb63bbbe01eeed093cb22bb8f5acdc3
SHA-256("hello world") = b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

A good cryptographic hash has three security properties:

  1. Preimage resistance: given a digest, it is infeasible to find any input that produces it.
  2. Second-preimage resistance: given an input, it is infeasible to find a different input with the same digest.
  3. Collision resistance: it is infeasible to find any two different inputs with the same digest.

It should also show the avalanche effect: changing a single bit of input changes about half the output bits, so similar inputs have completely unrelated digests. Try it in a hash generator: "hello world" and "hello world!" produce digests with nothing in common.

A short history of MD5

Ron Rivest designed MD5 in 1991. It was fast and became ubiquitous: file checksums, password storage, digital certificates. Weaknesses appeared within a few years, and in 2004 researchers demonstrated practical collisions. By 2008, a team created a rogue certificate authority certificate by exploiting MD5 collisions, and in 2012 the Flame malware used an MD5 collision to forge Microsoft code-signing certificates. Today, generating an MD5 collision takes seconds on a laptop.

Preimage attacks on MD5 remain theoretical, but collision resistance is completely broken, and that is enough to rule it out for signatures, certificates and integrity checks where an attacker might be involved.

SHA-1: also retired

SHA-1, with 160-bit output, followed a similar path. Theoretical weaknesses were published in 2005, and in 2017 Google and CWI Amsterdam produced the first real collision ("SHAttered"): two different PDF files with the same SHA-1 hash. Browsers stopped accepting SHA-1 certificates, and Git is migrating to SHA-256. Treat SHA-1 like MD5.

SHA-256 and the SHA-2 family

SHA-2, published by NIST in 2001, includes SHA-224, SHA-256, SHA-384 and SHA-512. SHA-256 is the most widely deployed: TLS certificates, code signing, Bitcoin, package managers, Subresource Integrity, JWT signatures (HS256 and RS256) and much more. After more than two decades of analysis, no practical attacks exist against its collision or preimage resistance.

SHA-512 uses 64-bit operations and is often faster than SHA-256 on 64-bit CPUs without hardware acceleration. SHA-384 is a truncated SHA-512 that also resists length-extension attacks.

SHA-3

SHA-3 (Keccak), standardised in 2015, uses a completely different internal design — a sponge construction — so a breakthrough against SHA-2 would not automatically affect it. It is not a replacement for SHA-2 so much as a backup with different properties. Use it where a specification requires it; otherwise SHA-256 remains the pragmatic default.

Side-by-side comparison

Algorithm Output size Collision resistance Status
MD5 128 bits Broken (seconds) Not for security
SHA-1 160 bits Broken (2017) Not for security
SHA-256 256 bits Secure Recommended default
SHA-512 512 bits Secure Recommended
SHA3-256 / SHA3-512 256 / 512 bits Secure Recommended alternative
BLAKE3 256 bits (extensible) Secure Very fast, growing adoption

Speed

MD5 is faster than SHA-256 in pure software, but the gap matters less than people think. Modern x86 and ARM processors include SHA-256 hardware instructions, which make SHA-256 run at gigabytes per second. In practice, reading a file from disk or the network is usually the bottleneck, not hashing. If raw speed is critical for non-security uses, BLAKE3 or non-cryptographic hashes such as xxHash beat both.

When MD5 is still acceptable

MD5's collision weakness only matters when someone can deliberately craft inputs. It remains acceptable for:

  • Detecting accidental corruption in transfers or storage when no attacker is involved.
  • Cache keys and deduplication of trusted data, for example bucketing your own files.
  • Legacy compatibility, such as systems that only publish MD5 checksums or protocols that require it.

Even in these cases, choosing SHA-256 costs little and removes the need to argue that no attacker could ever be involved. Many incidents started with a checksum that was "only for corruption" being relied upon for security later.

Verifying downloads correctly

When a project publishes a SHA-256 checksum, compute the hash of your download and compare every character:

sha256sum ubuntu.iso          # Linux
shasum -a 256 ubuntu.iso      # macOS
Get-FileHash ubuntu.iso       # Windows PowerShell

A matching checksum proves the file matches what the publisher hashed. It does not prove the publisher is legitimate: if an attacker controls the website, they can replace both file and checksum. Signed checksums (GPG or Sigstore) close that gap.

HMAC: hashing with a key

A plain hash proves integrity but not authenticity — anyone can compute it. HMAC combines a secret key with the message, so only parties with the key can produce or verify the result. Webhooks from Stripe, GitHub and Slack use HMAC-SHA256 signatures, and JWTs signed with HS256 are HMAC-SHA256 under the hood.

Do not build your own keyed hash by concatenating secret + message and hashing it. With MD5, SHA-1 and SHA-256, this is vulnerable to length-extension attacks. Use the standard HMAC construction, which every language provides. When comparing signatures, use a constant-time comparison function to avoid timing attacks.

Passwords need a different tool entirely

Neither MD5 nor SHA-256 should be used directly to store passwords. Fast hashes are a disadvantage here: a modern GPU computes billions of SHA-256 hashes per second, so an attacker who steals your database can test enormous lists of likely passwords quickly. Unsalted hashes are worse, because precomputed tables crack common passwords instantly.

Use a password hashing function designed to be slow and memory-hard:

  • Argon2id — the winner of the Password Hashing Competition and the current first choice.
  • scrypt — memory-hard and widely available.
  • bcrypt — older but still acceptable, with a 72-byte input limit.
  • PBKDF2 with a high iteration count — when compliance requires NIST-approved primitives.

These functions add a unique salt per password and a configurable cost factor that you can increase as hardware gets faster. Libraries handle the details: you call hash(password) and verify(password, stored).

Encoding digests

Digests are raw bytes, usually displayed as hexadecimal (two characters per byte) or Base64 (more compact). The same SHA-256 digest is 64 hex characters or 44 Base64 characters. Subresource Integrity attributes use Base64 (sha384-...), while checksums files use hex. For more on the encoding side, see Base64 explained.

Decision guide

  • Integrity check, signatures, certificates, anything security-related: SHA-256 (or SHA-512, SHA-3, BLAKE3).
  • Authenticating messages with a shared secret: HMAC-SHA256.
  • Storing passwords: Argon2id, scrypt or bcrypt — never a plain hash.
  • Non-adversarial checksums or cache keys: MD5 works, but SHA-256 is the safer habit.
  • Very high-speed non-security hashing (hash tables, sharding): xxHash or similar non-cryptographic hashes.

Summary

MD5 and SHA-1 are broken for collision resistance and must not be used where an attacker could benefit from crafting inputs. SHA-256 is secure, fast with hardware support and the right default for integrity and signatures. Use HMAC for keyed authentication and dedicated slow functions such as Argon2id for passwords. When in doubt, choose SHA-256 — it is never the wrong answer for integrity, and MD5 increasingly is.

Related guides