SHA-256, MD5, and Why You Should Never Use a Fast Hash for Passwords
The hash function is one of the most useful primitives in software. Give it any input, get back a fixed-size fingerprint of that input. The same input always produces the same fingerprint. Different inputs produce different fingerprints with overwhelming probability. From those two properties, you can build file integrity checking, content-addressable storage, digital signatures, deduplication, and a hundred other things. Git is built on top of them. Bitcoin is built on top of them. Modern HTTPS is built on top of them.
But the wrong hash for the wrong job is a disaster, and the most common wrong-hash-for-the-wrong-job is using a fast hash like SHA-256 to store passwords. This post explains what each hash is good for and which to reach for in each case.
What a cryptographic hash actually is
A cryptographic hash function has three properties:
- Deterministic. Same input always produces the same output.
- Collision-resistant. Finding two different inputs that produce the same output should be computationally infeasible.
- Preimage-resistant. Given an output, finding any input that produces it should be computationally infeasible.
These properties together mean that the hash of a file is, in practice, a unique fingerprint of that file. You can put the hash in a public place and use it to verify that a file someone gives you later is the same file. You cannot reverse-engineer the file from the hash.
SHA-256 and SHA-512: the modern defaults
SHA-256 is the standard hash function for almost everything in 2026. It produces a 256-bit (32-byte) output, conventionally rendered as 64 hex characters. It is used in TLS certificate fingerprints, Bitcoin block hashes, file integrity checks, and content-addressable storage systems. Git is moving from SHA-1 to SHA-256 for object hashing.
SHA-512 is the same algorithm family with larger output (512 bits, 128 hex characters). It is slightly faster than SHA-256 on 64-bit hardware because its internal operations are natively 64-bit. Use it when you have a specific need for the larger output (some protocols require it) or when computing many hashes on modern hardware.
Both SHA-256 and SHA-512 are secure for the foreseeable future. There are no known practical attacks against either; the best known attacks reduce the security margin slightly but do not enable real collisions.
SHA-1: deprecated but still around
SHA-1 was the default cryptographic hash for years. In 2017, the SHAttered attack demonstrated a practical collision (Google produced two PDF files with the same SHA-1 hash). After that, SHA-1 was deprecated for any use where collision resistance matters. Most TLS certificate authorities stopped issuing SHA-1-based certificates.
SHA-1 still appears in some places: git still uses SHA-1 for object hashes (the migration to SHA-256 is in progress), some legacy protocols use it for non-security purposes, and TLS sometimes uses it for HMAC (where collision resistance is not required and SHA-1 is still safe).
For new uses, do not pick SHA-1. For verifying a SHA-1 hash that already exists in a system, use it for that specific purpose but flag for migration.
MD5: broken but still useful
MD5 has been broken for cryptographic purposes since the early 2000s. Practical collisions can be generated in seconds on a laptop. Anyone telling you to use MD5 for security is wrong.
That said, MD5 is still useful for non-security purposes: detecting accidental file corruption, content-based deduplication (where adversarial collisions are not the threat), cache keys for memoization. The Toolium Hash Generator still computes MD5 because these uses are legitimate, but it labels MD5 as "not for security use."
The password storage problem (and why SHA-256 is wrong)
Here is the case that bites every junior developer at some point. The natural-sounding approach to password storage is: take the user's password, compute SHA-256 of it, store the hash. On login, hash the entered password and compare to the stored hash.
This is wildly insecure. The reason: SHA-256 is fast. A modern GPU can compute billions of SHA-256 hashes per second. If an attacker steals your password hash database, they can run a wordlist attack at billions of guesses per second and crack most weak passwords in seconds.
The fix is to use a deliberately slow hash function. bcrypt, scrypt, argon2, and PBKDF2 are the four major options. They are designed to take milliseconds-to-seconds per hash even on the fastest hardware, which makes brute-force attacks infeasible. The Toolium hash generator does not produce these because they require parameters (cost factor, salt, etc.) and the right answers depend on context; use your language's library implementation.
The rule: SHA-256 for everything except password storage. For password storage, bcrypt (or argon2 if you are starting fresh in 2026).
Salting
Even with a slow hash function, you still need to salt the passwords. A salt is a random string mixed in with the password before hashing. Without salts, two users with the same password produce the same hash; an attacker can compute a "rainbow table" of common password hashes and look up matches.
With per-user salts, every user's hash is different even if their passwords are identical. The salt is stored alongside the hash; it is not secret, but it is unique per user.
Modern libraries (bcrypt in particular) handle salting automatically. You do not need to think about it as long as you use a real library.
Common uses for SHA-256
- File integrity verification. Many software downloads publish a SHA-256 of the file. After downloading, compute the SHA-256 of your copy and compare. If they match, the file is intact.
- Content-addressable storage. Use the hash of content as its identifier. Same content produces same identifier, automatically deduplicating.
- HMAC. A keyed message authentication code, built from SHA-256, used for verifying webhook signatures (Stripe, GitHub) and API request integrity.
- Digital signatures. Sign the SHA-256 of a document with a private key. The signature is small and verifying it does not require re-hashing on every check.
- Git object IDs. (Currently SHA-1, migrating to SHA-256.) Each git object is identified by the hash of its content.
The Toolium tool
The Hash Generator computes MD5, SHA-1, SHA-256, and SHA-512 of any text input. The computation happens entirely in your browser using the SubtleCrypto API (for SHA variants) and a lightweight MD5 library. No upload, no logging. If you are verifying a download or computing a content fingerprint, the data does not leave your computer.
Try the tool mentioned in this article
Open tool