compscai
Website Security
· · 0 responses

What is Password Hashing?

Website Security

If your database ever leaks, password hashing is the difference between "we had an incident" and "every user's password is now public." After writing up SQL injection, this felt like the natural next post, because the two go together. SQLi is one of the classic ways a passwords table ends up in the wrong hands, and hashing is what decides how bad that day gets.

The core idea

You never store the password. You store a fingerprint of it.

A hash function takes an input and produces a fixed-size scramble of it. Same input, same output, every time. But there's no way to run it backwards. Given the hash, you can't compute the password that made it.

So the login flow looks like this: when a user signs up, you hash their password and store the hash. When they log in later, you hash whatever they typed and compare it to the stored one. If the hashes match, the passwords matched. At no point did you need to keep the actual password around.

That means even you, the site owner, can't look up a user's password. That's not a limitation, that's the whole point. If a site can email you your old password, run.

Why plain hashing isn't enough

Here's the catch I didn't appreciate at first. A plain hash like SHA-256 is deterministic, so "password123" hashes to the same value on every site in the world. Attackers know this, and they've precomputed the hashes for billions of common passwords. Crack one table like that and you've cracked them all. Two users with the same password also get the same hash, which leaks information all by itself.

The fix is a salt: a random value generated per user and mixed into the password before hashing. The salt gets stored right next to the hash, in plain view, and that's fine. It's not a secret. Its job is to make every hash unique, so precomputed tables are useless and the attacker has to crack each password individually.

Slow on purpose

The second thing that surprised me is that good password hashing algorithms are deliberately slow.

Regular hash functions are built for speed, and a GPU can run SHA-256 billions of times per second. That speed is great for checksums and terrible for passwords, because cracking is just guessing at scale. Algorithms like bcrypt and Argon2 are designed the other way around. They have a cost setting that makes each hash take real work, tens of milliseconds instead of nanoseconds, and Argon2 also demands a chunk of memory so GPUs lose their edge.

A user logging in never notices 50 milliseconds. An attacker trying ten billion guesses notices it a lot. Same operation, but the economics flip completely.

The cost setting is tunable for a reason. Hardware gets faster every year, so what counts as "slow enough" moves. You can raise the cost later and rehash passwords as people log in.

What this looks like in practice

The good news is you shouldn't be assembling salts and hashes by hand. Every serious language has this solved. This site is PHP, where it's two functions:

php
// signup: salt is generated and baked into the output for you
$hash = password_hash($password, PASSWORD_DEFAULT);

// login
if (password_verify($input, $hash)) { /* they're in */ }

That's it. The salt, the algorithm, the cost, all handled and stored inside the hash string itself. The main ways to get this wrong are inventing your own scheme or picking a fast hash because it seemed fine. Boring and standard wins here.

The takeaway

Hashing is damage control you set up in advance. It assumes the breach will happen someday, through an injection bug, a leaked backup, whatever, and makes sure that what leaks is a pile of expensive-to-crack fingerprints instead of a spreadsheet of logins. Salting makes every hash unique. Slowness makes guessing costly. And a library does all of it in one line, so there's really no excuse to store anything else.

0 responses