Take any data you like, a three-word note or a three-terabyte backup, and a hash function will crush it into a short fingerprint of fixed size, say 256 bits. Same input, same fingerprint, every time, on every machine. Change a single comma and the fingerprint changes completely, into something unrecognizably different. And here is the strange part: nobody, including the person who computed it, can run the process backward. That deliberate irreversibility turns out to be one of the most useful properties in all of computing.

Hashing is the third tool in the cryptographic toolbox, alongside the two encryption families covered in the pillar article, how encryption actually works. Unlike encryption, hashing has no key and no decryption. It is not for hiding data. It is for fingerprinting it.

What makes a hash cryptographic

Any function that maps big inputs to small outputs is technically a hash. Your programming language uses cheap ones to organize data in memory. A cryptographic hash function has to survive an adversary, which demands three specific properties.

Preimage resistance: given a digest (the output fingerprint), it must be infeasible to find any input that produces it. The function is a one-way street for everyone, with no trapdoor and no shortcut.

Second preimage resistance: given one input, it must be infeasible to find a different input with the same digest. Otherwise someone could swap a signed contract for a forged one with a matching fingerprint.

Collision resistance: it must be infeasible to find any two inputs with the same digest, even when the attacker gets to choose both freely. This is the strictest demand, and it is always the first to fall.

Note the wording: infeasible, not impossible. A 256-bit digest can take only 2^256 values while inputs are unlimited, so collisions exist in infinite abundance. The pigeonhole principle guarantees it. The security claim is that the digests are spread so uniformly and unpredictably that finding a collision on purpose requires brute-force search through a space of roughly 2^128 attempts (birthday-paradox math halves the exponent), which is comfortably beyond planetary computing resources.

The workhorse today is SHA-256, one of the SHA-2 family standardized by NIST. It produces 256-bit digests and sits inside TLS certificates, software signatures, Git in its newer configurations, and Bitcoin's entire mining mechanism. A newer family, SHA-3, was standardized in 2015 with a completely different internal design, mostly as insurance in case SHA-2 ever cracks.

How the old ones died

The instructive stories in hashing are the failures. MD5, designed in the early 1990s, produces 128-bit digests and was everywhere for a decade. Cryptanalysts found growing structural weaknesses, and in 2004 researchers demonstrated real collisions. The attacks matured with alarming speed: within a few years, generating an MD5 collision took seconds on a laptop, and in 2008 researchers used the weakness to forge a working certificate authority certificate, the kind of credential that underpins the trust system described in what TLS actually does. The Flame espionage malware, discovered in 2012, exploited an MD5 collision to disguise itself as legitimately signed Windows software.

SHA-1, MD5's stronger sibling with 160-bit digests, followed the same arc more slowly. Theoretical cracks appeared in 2005, and NIST deprecated it for digital signatures in 2011; although the formal cutoff for all US government use is 2030, browsers, certificate authorities, and major platforms had already abandoned SHA-1 for certificates and code signing years earlier, and industry practice today treats it as unacceptable outright. The theoretical became concrete in 2017, when researchers at Google and CWI Amsterdam published two different PDF files with identical SHA-1 digests, a computation that cost thousands of GPU-years but was entirely practical for a well-funded attacker. Browsers had already stopped accepting SHA-1 certificates around that time.

The moral is not that hash functions are fragile. It is that collision resistance erodes gradually and publicly, usually with years of warning between "researchers found structure" and "attacks are practical." The systems that got burned were the ones that ignored the warnings.

Passwords: where fast hashing becomes a bug

Hashing seems tailor-made for passwords. Store the digest instead of the password; at login, hash what the user typed and compare. Even if the database leaks, attackers hold only irreversible fingerprints. Right?

Half right, and the wrong half has cost companies dearly. The catch is that users don't pick random 256-bit inputs; they pick "sunshine2019". An attacker with leaked digests doesn't need to invert anything. They guess likely passwords, hash each guess, and compare. This is where SHA-256's greatest virtue, blistering speed, becomes a liability: a single modern GPU computes billions of SHA-256 hashes per second, enough to sweep through every dictionary word, name, date, and common mutation in minutes.

Two countermeasures are standard, and both are about economics rather than secrecy.

Salting. Before hashing, append a unique random value (the salt, stored openly next to the digest) to each password. Now identical passwords produce different digests, precomputed lookup tables become useless, and the attacker must run the full guessing attack separately against every single account.

Deliberate slowness. Replace the sprinter with a designated slowpoke. Algorithms like bcrypt, scrypt, and Argon2 (winner of the Password Hashing Competition in 2015) are engineered to be expensive, with a tunable cost knob, and the newer ones also demand large amounts of memory, which neutralizes the GPU's advantage of thousands of parallel cores. Tuned so a login check takes a tenth of a second, they slow the defender imperceptibly while cutting the attacker's guess rate by factors of millions.

Salted plus slow is the entire recipe, and "we hashed passwords with raw MD5" remains one of the most common confessions in breach disclosures.

Stacking hashes: Merkle trees

One more construction earns its keep everywhere: hash the pieces of a dataset, then hash the pairs of digests, then pairs of those, until a single root hash summarizes everything. This is a Merkle tree, named after Ralph Merkle, who proposed the idea in the late 1970s.

The payoff is efficient spot-checking. To prove one piece belongs under a given root, you present only the digests along that piece's path upward, about twenty of them for a million pieces. Git identifies every version of your code this way, BitTorrent verifies chunks received from strangers, certificate transparency logs use it to make any tampering with the record publicly evident, and Bitcoin's blocks summarize thousands of transactions under one root. Anywhere you see "verify a part without trusting the whole," a Merkle tree is usually underneath.

Hashes also team up with the asymmetric keys from symmetric vs asymmetric encryption: digital signatures never sign a document directly, they sign its digest, which is why collision attacks on the hash translate into forgery attacks on the signature.

The takeaway

A hash function is a fingerprinting machine: any input, one fixed-size digest, no way back, and no two inputs that collide on purpose. That small contract quietly supports file integrity, signatures, password storage, version control, and blockchains. Its failure mode is slow and public, as MD5 and SHA-1 showed, and its sharpest practical lesson is that passwords need salted, deliberately slow hashing rather than raw speed. If you enjoy having a five-minute working model of machinery like this before you build on it, that is precisely the kind of primer NerdSip serves daily, and the rest of this cluster builds on hashing everywhere, from RSA signatures to the padlock in your browser.