formaterTools Logo Formater Tools

MD5 vs SHA-256: What Hashing Actually Proves (and Doesn't)

"MD5 is broken" is one of those things everyone repeats without necessarily being able to say what it means. Broken how? It still produces a 128-bit fingerprint every time you feed it a string, and that fingerprint still changes completely if you flip one character of the input. The truth is more specific than "broken" implies: MD5 is broken for exactly one narrow purpose - resisting an attacker who wants to forge a matching hash - and it's still fine for a bunch of other things people use hashes for. Getting clear on which is which is the whole point of understanding what a hash actually proves.

What a Hash Function Actually Guarantees

A cryptographic hash function takes an input of any length and produces a fixed-length output - the "digest" - through a one-way transformation. One-way means there's no practical way to run the process backward: you cannot take a SHA-256 digest and recover the original text it came from, the way you could reverse Base64 or decrypt a properly-keyed cipher. The same input always produces the exact same digest, every time, on every machine - that determinism is what makes hashes useful as fingerprints in the first place. And a well-designed hash exhibits the "avalanche effect": changing a single character of the input should flip roughly half the bits of the output, so similar inputs never produce similar-looking hashes. Hash password and Password and the two digests share nothing recognizable in common, despite differing by a single capital letter.

None of that is the same claim as "no two inputs will ever produce the same output." With a fixed-length output and infinite possible inputs, collisions - two different inputs hashing to the same digest - are mathematically guaranteed to exist somewhere in the space of all possible strings. What a hash function is supposed to guarantee is that finding one of those collisions is computationally infeasible. That guarantee is exactly what broke for MD5 and SHA-1, and exactly what still holds for SHA-256.

Why "Broken" Means "Collisions Are Findable," Not "Reversible"

MD5 has had practical collision attacks since 2004, and by now two colliding MD5 inputs can be constructed in seconds on ordinary hardware. SHA-1 held out longer, but Google and CWI Amsterdam demonstrated a real, working collision in 2017 - two different PDF files that hash to the identical SHA-1 digest, an attack researchers called "SHAttered." In both cases, the break is the same shape: someone found a way to deliberately construct two different inputs that hash identically, far faster than brute-force guessing should allow. Nobody reversed a hash back into its original input - that still isn't possible for either algorithm. What broke is the promise that you can trust a matching hash as proof two things are the same, when an adversary controls one of the inputs.

That distinction is why MD5 still shows up in places that would surprise you if "broken" meant "useless." Confirming a large file wasn't corrupted during a transfer, generating a cache-busting key from a resource's contents, deduplicating identical records in a dataset - none of these involve an adversary trying to forge a matching hash, so the collision weakness never gets exercised. Where it matters is anywhere an attacker could choose or influence the input: verifying a security-sensitive download from an untrusted source, checking a digital signature, or anything where "these two things hash the same" is being used as proof of authenticity against someone who might want to fake that proof. That's the line - not whether MD5 "still works," but whether anyone hostile gets to pick what goes into it.

SHA-2: Same Idea, No Known Practical Break

SHA-256, SHA-384, and SHA-512 - the SHA-2 family - are built on a different, more resistant internal structure than MD5 or SHA-1, and no practical collision attack against any SHA-2 variant is currently known. SHA-256 (producing a 64-character hex digest) is the default for TLS certificate fingerprints, Bitcoin block hashing, and most "verify this download checksum" instructions today. SHA-384 and SHA-512 produce longer 96- and 128-character digests and run on 64-bit words internally, which on modern 64-bit hardware can make them slightly faster than SHA-256 despite the longer output - a detail worth knowing before assuming "longer output means slower."

This site's Hash Generator computes these five algorithms two different ways under the hood, and it's worth knowing which is which if you're relying on the output. Browsers don't expose MD5 through the native Web Crypto API - it was deliberately excluded for security reasons - so MD5 here runs on a hand-rolled JavaScript implementation of the RFC 1321 algorithm, real bitwise rotations and modular addition executing in your tab. SHA-1, SHA-256, SHA-384, and SHA-512, by contrast, call the browser's built-in crypto.subtle.digest(), running natively rather than in interpreted JavaScript - which is also why MD5 can feel comparatively slower on very large input: it's pure JS competing against audited native code. One more detail worth knowing if you're cross-checking a hash against a command-line tool: the text you paste into this tool is .trim()'d before hashing, so a stray trailing newline that a script like sha256sum wouldn't strip can produce a mismatch that has nothing to do with the algorithm itself.

Why Hashing a Password Directly Is Still the Wrong Move

Here's where the collision conversation is almost a distraction, because collision resistance was never the property that mattered for password storage in the first place. If you take a user's password and run it through SHA-256 - a perfectly uncompromised, collision-resistant algorithm - and store that digest in your database, you have still built an insecure authentication system. The problem isn't that SHA-256 is weak. The problem is that it's fast, and fast is a liability, not a feature, when the thing you're hashing is a secret someone is trying to guess.

A modern GPU can compute billions of SHA-256 hashes per second. If an attacker steals your database of unsalted SHA-256 password hashes, they don't need to reverse any of them - they just hash every password in a breach dictionary (there are lists with billions of real, previously-leaked passwords) and check for matches, or brute-force short passwords directly, all at GPU speed. Two users with the identical password get the identical hash, which means a single successful guess against one account's hash silently cracks every other account using that same password. This is precisely the gap the Hash Generator is upfront about: there's no salt field on that tool, because it's a plain digest generator, not a password storage scheme - hashing the same input twice there will always produce the identical output, the same property that makes rainbow-table lookups against unsalted password hashes trivial in the real world.

Real authentication systems fix this with two things a plain SHA-256 call doesn't give you. First, a unique, random salt per user, mixed into the input before hashing, so identical passwords produce different stored hashes and a precomputed rainbow table becomes useless. Second - and this is the part that actually addresses the speed problem - a deliberately slow, computationally expensive algorithm like bcrypt, scrypt, or Argon2, which are designed to take a noticeable fraction of a second per hash even on fast hardware, specifically so that checking billions of guesses becomes impractically slow for an attacker while remaining a non-issue for the one legitimate login check per request your server actually needs to do. SHA-256 was designed to be as fast as possible for exactly the use cases described above - checksums, fingerprints, signatures - and that design goal is the opposite of what you want for a password.

Where That Leaves the Choice

For checksums, deduplication, cache keys, and anything else where nobody hostile controls the input, MD5 still works fine and its speed is an advantage rather than a risk. For anything where a matching hash needs to prove authenticity against someone who might try to fake it - downloads, signatures, commit integrity in newer systems - SHA-256 or better is the only reasonable choice, since no practical collision attack against it exists. And for passwords specifically, the right answer isn't "which fast hash function" at all - it's a purpose-built slow algorithm with per-user salting, running on your server, not a single call to any hash function you'd reach for on this page.

You can generate and compare MD5, SHA-1, SHA-256, SHA-384, and SHA-512 digests of any text with the Hash Generator - useful for checksums, spot-checking a fingerprint, or seeing the avalanche effect for yourself, with the password-storage caveat above firmly in mind for anything beyond that.