Storing a scrambled, one-way version of a password instead of the real thing, so even the company never knows it.
Why it exists
A product must check passwords, but storing them as plain text means one database leak hands attackers every account, and people reuse passwords everywhere. Keeping the real password around is the danger. Password hashing exists to store only a one-way scramble of the password, so the system can verify a login without ever holding the secret it could lose.
How it actually works
Storing real passwords would be catastrophic; one breach and every account is exposed. Instead, the server runs the password through a one-way scramble (a hash) and stores only the result. The scramble cannot be reversed.
When you log in, the server scrambles what you typed and compares the two scrambles. Match means correct. This is why support can reset your password but never tell you what it was: nobody, not even the database, holds the original.
A senior PM walks you through it
A junior PM, stuck
A CX lead asked me why support cannot just email a customer her forgotten password, since surely we have it in our database, and I could not give a straight answer. I said something vague about security and felt like I was guessing. I need to actually understand what the users table holds so I can explain it without hand-waving.
We do not have her password, and the proof is one column in the users table. What we store is a one-way scramble of the password, and one-way means exactly that: there is no way to run it backwards into the original. Here is the real password_hash value from one row, split into its parts, and next to it what the server does at login, so you can see it check a password without ever holding one.
The password_hash column for one users row, and the login-time check
The stored hash, split at its separators
1$2b$
212$
3R9h/cIPz0gi.URNNX3kh2O
4PST9/PgBkqquzi.Ss7KIUgO2t0jWMUW
What the server does when she logs in
5input: the password she just typed
6run bcrypt(input) using the salt from the stored hash
7compare the fresh digest to the stored digest
8equal: login ok not equal: reject
Click a step to see the lines it points at.
Mistakes I've seen
Telling a customer support can look up her old password. Support can only reset it; the plaintext exists nowhere, so a retrieve-my-password flow cannot be built correctly no matter how the ticket is worded.
Calling hashing the same thing as encryption. Encryption is reversible with a key, on purpose; a password hash is deliberately one-way with no key that turns it back, and conflating them leads to asking engineers for something impossible.
Waving off the salt as a technical detail. Without the per-user salt, identical passwords hash identically and one leaked table cracks in bulk against a precomputed list.
Treating the cost factor as noise. It is the dial between a login that is fast for the user and expensive for an attacker, and quietly lowering it to speed up sign-in weakens every account in the table.
Tell the CX lead: "We can't email her the password because we never store it. The users table holds only a one-way bcrypt hash, so nobody, including us, can read the original. The correct flow is a reset link that lets her set a new one." You read a hash into its algorithm, cost, salt, and digest, and could explain why the original is gone for good. That is the skill.
Where a PM meets this
"We don't store passwords" is the correct, expected answer. If anyone suggests keeping real passwords, that is a red flag.
This is why password reset means setting a new one, never "here is your old password." Understanding that shapes the reset flow you design.
Hear it in a meeting
"We can't email them their password, we only store the hash. Send a reset link."