"Hashing guarantees the file is unchanged" and "hashing stores passwords" use the same function but need security properties in opposite directions. Conflating them causes two distinct failures: treating MD5 as tamper protection, or treating SHA-256 as password storage. This article draws that boundary.
The first question for any hash decision is whether an attacker would deliberately construct input. In non-adversarial settings — file checksums, cache keys, ETags, data sharding — problems come from random factors such as transfer errors or disk faults, and nobody has motivation to build collisions for you. In adversarial settings — tamper protection, signatures, password storage — an attacker has both motive and resources, so the algorithm must assume they will look for weaknesses. This distinction explains why "is MD5 usable" depends entirely on the use case, and why one algorithm can be simultaneously acceptable and unacceptable.
For file verification there are two paths. CRC32 is designed specifically for detecting transfer errors and is one to two orders of magnitude faster than SHA-256, but its collision resistance is weak (32 bits, collision probability grows with the square of file count) — suitable for confirming a download completed intact. SHA-256 is a cryptographic hash with strong collision resistance and no known practical attack, suitable for tamper protection. The in-site hashing tool computes SHA-256 because it suffices for both cases at the cost of speed; CRC32's advantage only matters when validating hundreds of files per second in a build pipeline.
MD5 and SHA-1 need a clear statement. MD5 collisions can now be produced in seconds on an ordinary laptop. SHA-1's SHAttered attack was published in 2017 at roughly 45k dollars, a cost that keeps falling. One technical nuance: a collision attack is not the same as recovering an arbitrary original message, which requires a second-preimage attack and is far harder. But for file replacement, collision is already sufficient — prepare legitimate file A and malicious file B with identical hashes, swap them, and the checksum still matches while the content changed. For anything new, use SHA-256.
Password storage is the critical section. General-purpose hashes are fast, which is precisely what password storage must not be: a GPU computes billions of SHA-256 per second, so testing a leaked hash list against a rainbow table takes minutes. Password hashes must be deliberately slow and satisfy two conditions. First, automatic salting, so identical passwords yield different hashes and one rainbow table fails for every user; the salt need not be secret but must be unique. Second, a tunable cost parameter, so brute force gets more expensive as hardware improves without changing the data format. Argon2id is the preferred choice, with bcrypt, scrypt and PBKDF2 as alternatives that all meet the bar. Never store passwords as plain SHA-256: no salt, no cost parameter, far too fast.
A subtle but serious error is hand-rolling hash(secret + body) for webhook signature verification. This construction has a length-extension weakness: an attacker who does not know the secret can still produce a valid signature over secret || body || padding || extra, appending arbitrary content to a message that still verifies. SHA-256 is collision resistant but not length-extension resistant, while SHA-3 and BLAKE2 are. Use HMAC instead, which addresses this by design through two rounds of mixing rather than simple concatenation. One related rule: compare any token or signature with timingSafeEqual rather than ===, because string equality returns at the first differing character and the timing difference lets an attacker recover the correct value byte by byte.
Migrating legacy hashes does not require a flag day. The standard approach is upgrade on login: verify with the old algorithm, then immediately re-hash with the KDF and store it. The elegance is that only real users trigger the upgrade, so an attacker's stolen hash list is never refreshed. As legitimate users log in, old hashes are replaced naturally. A password strength tool helps assess resistance to cracking and supports policies that reject weak passwords.