In 2012, LinkedIn lost 6.5 million passwords. Every single one was hashed. Every single one was cracked. The question was never whether the attacker had the hash — it was whether the hash was worth having.

Let that sink in for a moment.

Six and a half million passwords. Hashed. Exposed. Cracked — some within hours. The engineers at LinkedIn were not incompetent. They used SHA-1, which was considered reasonable at the time. And yet, attackers tore through those hashes like a knife through paper.

Act I — The Locksmith's One-Way Door (Hashing)

Imagine a locksmith who builds a magical machine. You feed it any message — a love letter, a grocery list, your bank password — and it spits out a fixed-length string of characters. No matter how long your input is, the output is always the same length. And here is the part that makes it extraordinary: you cannot reverse the process. The machine chews your input and produces a fingerprint. You cannot reconstruct the original from the fingerprint alone.

That machine is a hash function. That fingerprint is a hash digest.

How It Works — The Technical Reality

A hash function is a deterministic mathematical algorithm. Feed it the same input and you always get the same output. Change a single character in your input and the output changes completely. This is called the avalanche effect.

Consider SHA-256, one of the most widely used hash functions today:

Input: "password"

Output: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

Input: "Password" (one capital letter changed)

Output: e7cf3ef4f17c3999a94f2c6f612e8a888e5b1026878e4e19398b23bd38ec221a

Two wildly different outputs from nearly identical inputs. Unpredictable. That is the avalanche effect doing its job.

Hash functions have four critical properties: pre-image resistance (you cannot reverse the hash), second pre-image resistance (you cannot find a different input that produces the same hash), collision resistance (no two inputs should produce the same output), and determinism (same input always yields the same output).

Real-World Example: Password Storage

When you register on a website, a properly designed system never stores your actual password. It stores the hash of your password. At login, the system hashes what you typed and compares it to the stored hash. If they match, access is granted.

This means even the database administrator cannot read your password — only a meaningless hex string exists in storage. Elegant, right?

⚡ Penetration Tester's Note

When you dump a database during an engagement and find columns full of hex strings, those are likely hashed passwords. Your next step: identify the hash type using hashid or hash-identifier, then launch an offline cracking attack with Hashcat or John the Ripper.

The Weakness — Rainbow Tables and the Lookup Economy

Here is where the story turns dark.

Attackers are patient and clever. Since hash functions are deterministic, they pre-computed the hashes of millions of common passwords and stored them in massive lookup tables called rainbow tables. When they steal a hash database, they simply look up each hash. No cracking required. Just a lookup.

Imagine you have just exfiltrated a database during a penetration test. You open it and find:

User: alice@example.com

Hash: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

You paste that hash into CrackStation — a public rainbow table database — and within seconds it returns: password. Alice literally used the word "password". No GPU farm required. Done.

This is precisely what happened to LinkedIn. The attackers did not break SHA-1 mathematically. They simply looked up pre-computed answers. Which is why hashing alone is dangerously insufficient.

Act II — Throwing Sand in the Attacker's Eyes (Salting)

The security community heard the criticism and responded with an elegant counter-move. If the problem is that the same password always produces the same hash — making lookup tables effective — then the solution is obvious: make sure the same password never produces the same hash twice.

Enter salting.

What Is a Salt?

A salt is a randomly generated string of data that is appended or prepended to a user's password before hashing. The salt is not secret — it is stored alongside the hash in the database. Its purpose is not secrecy. Its purpose is uniqueness.

User: alice@example.com

Salt: xK9#mP2$qR (random, unique per user)

Input to hash: password + xK9#mP2$qR = passwordxK9#mP2$qR

Stored: SHA256(passwordxK9#mP2$qR)

User: bob@example.com

Salt: Lz7!nW4@vT (different random salt)

Input to hash: password + Lz7!nW4@vT = passwordLz7!nW4@vT

Stored: SHA256(passwordLz7!nW4@vT)

Alice and Bob both use the password "password" — but their stored hashes are completely different. A rainbow table built for plain SHA-256 is now useless. The attacker would need to rebuild the entire table for every unique salt. Computationally infeasible.

Act III — The Lockbox with Two Keys (Encryption)

So far our story has been about one-way streets. Hash something and you cannot unhash it — intentional for passwords. But what about data you need to retrieve in its original form? Credit card numbers, medical records, API tokens, private messages? For that, we need encryption. And here the story splits into two very different roads.

The Attacker's Counter-Move — and Why Modern Algorithms Win

A sophisticated attacker blocked from rainbow tables switches to brute-force or dictionary attacks, using a GPU cluster and tools like Hashcat to try millions of combinations per second. This is where the choice of algorithm becomes critical.

SHA-256 is extremely fast. A modern GPU can compute billions of SHA-256 hashes per second. That speed is great for file integrity checking — and terrible for password storage. What you need for passwords is a deliberately slow algorithm:

These algorithms have a configurable cost factor. As hardware gets faster, you increase the cost factor to keep the algorithm expensive enough to frustrate offline attacks.

🔒 Pro Tip: In a penetration test, if dumped hashes start with $2a$ or $2b$, that is bcrypt — prepare for a slow cracking session. Plain MD5 or unsalted SHA-1 is a critical finding: document it as inadequate password storage controls.

Mistake 1: Encrypting Passwords Instead of Hashing Them

One of the most dangerous misconceptions. If passwords are encrypted, whoever holds the encryption key can decrypt every single user's password. A single key compromise becomes a total credential catastrophe. Passwords must be hashed — irreversibly. If a developer tells you they encrypt passwords, that is a critical finding.

Mistake 2: Hashing Data That Needs to Be Retrieved

The reverse error. An engineer stores credit card numbers as SHA-256 hashes thinking it is secure. But you can never retrieve the original number for payment processing. The correct approach is encryption with proper key management. Hashing is one-way by design — never use it for data you need to read back.

Epilogue — Back to LinkedIn

Remember where we started? LinkedIn, 2012. SHA-1. No salting. A blazingly fast algorithm. Millions of passwords cracked.

By contrast, when Dropbox disclosed their own 2012 breach four years later, security researchers found that despite the credential exposure, most accounts remained protected. Dropbox had used bcrypt with unique salts. The math simply did not allow fast cracking.

Same era. Same threat landscape. Completely different outcomes. The difference was a handful of lines in the authentication layer.

Cryptography does not fail because the math breaks. It fails because engineers make assumptions, take shortcuts, and implement without truly understanding what they are defending against.

As security professionals, our job is to find those shortcuts before the attackers do. To look at a hash column and ask: which algorithm? Salted? How many iterations? Could a GPU farm crack this over a weekend? To look at an encrypted field and ask: where is the key? Is it in the same database? Is it in a git repository somewhere?

Hashing, salting, and encryption are not checkbox features on a compliance form. They are a mindset. A commitment to understanding the adversary's playbook well enough to write a better one.

THANKS FOR YOUR TIME!