What happens when you set a password on a well-built site
Type a password into a signup form on a site that does things properly, and the plaintext you typed never gets stored anywhere. Before it touches a database, it gets run through a one-way hash function, an algorithm that turns your password into a fixed-length string of characters that looks nothing like the original. "hunter2" and "Xk9$mQp2vL!wRt7bN4" would both come out as a scrambled string of the same length, and there's no way to look at either output and guess what went in.
That output, the hash, is what actually gets written to the database. The plaintext password is discarded the moment the hash is computed. It exists in server memory for a fraction of a second and then it's gone. This is why "how does password hashing work" is really a question about deletion as much as transformation. The site isn't storing your password in a locked box somewhere. It stores a fingerprint of your password and throws the original away.
A real breach makes this concrete. In 2019, a security researcher found that Facebook had been logging hundreds of millions of user passwords in plaintext to internal systems, some going back to 2012, because a change to how passwords were validated accidentally wrote the raw text to log files before hashing happened. No customer data was reported stolen as a result, but the incident is a useful case study precisely because it shows what "doing it wrong" looks like in practice: a bug in the pipeline, not malice, is often how plaintext ends up somewhere it shouldn't.
One property of hashing worth understanding: the output is always a fixed length, no matter how long the input was. A single character or an entire novel run through SHA-256 both produce a 256-bit result. That's a deliberate design choice, not a coincidence. It means the database column storing password hashes never has to grow to accommodate a longer password, and it means the hash itself gives an attacker no clue about how long the original password was. A short weak password and a long strong one look identical sitting in the database, right up until someone tries to guess them.
Why can't companies see my password? Because they never had it
This is the part that trips people up, because it feels like a company that built your account should obviously be able to look up your password if you forget it. But a well-built system genuinely cannot. It only ever held your password for the instant it took to hash it. After that, the plaintext is gone, and a hash cannot be run backward into the string that produced it. That's the entire point of the algorithm.
So when you use "forgot password" on a legitimate site, you don't get your old password back. You get a link to set a new one, because a new one is all the system is capable of offering. If a "forgot password" flow instead emails you your actual old password in plain text, that's not a nice touch. It's evidence the site skipped hashing altogether and stored your password as-is. That's a serious security failure, and it means anyone who gains read access to that database (an attacker, a rogue employee, a misconfigured backup) has every user's password sitting there in the open, ready to use.
Treat that email the way you'd treat a doctor's office texting you someone else's test results: it shouldn't be possible, and the fact that it happened tells you something is broken behind the scenes. The right response is to change that password immediately, and change it anywhere else you reused it.
There's a second, quieter reason "why can't companies see my password" matters beyond that one awkward email. Customer support agents, database administrators, even the engineers who wrote the login system, all go through their day without ever seeing a live password, because the system was built so that nobody has to be trusted with one. That's a better security posture than trusting individual employees to behave, since it removes the option entirely rather than relying on policy or good intentions. A support rep can reset your password. They can't read it back to you over the phone, no matter how nicely you ask, because the plaintext simply isn't sitting anywhere for them to find.
Bcrypt vs SHA-256 for passwords: why "any hash" isn't good enough
Not all hash functions are built for the same job, and this is where a lot of otherwise well-intentioned developers get it wrong. Algorithms like MD5 and SHA-256 are general-purpose hashes. They're designed to be fast, and you'd want that speed if you're checksumming a large file or verifying a Git commit hasn't changed. Speed is a feature there.
Speed is exactly the wrong property for a password hash. If an attacker gets hold of a database of SHA-256 password hashes, they can try billions of candidate passwords per second against them using consumer graphics hardware, because SHA-256 was built to run fast on exactly that kind of parallel hardware. A modern GPU rig can push several billion SHA-256 hashes per second; the same rig running bcrypt at a reasonable work factor might manage a few thousand per second. That's not a small gap. It's the difference between cracking a weak password list in minutes and it taking years, using the same hardware and the same stolen database.
That gap is why purpose-built password hashing algorithms exist: bcrypt, scrypt, and Argon2. They're deliberately, tunably slow. Bcrypt has a "cost factor" you can dial up as hardware gets faster, so the same algorithm from 2009 still resists modern GPUs by simply making each guess more expensive to compute. A cost factor of 10, a common default, means roughly a tenth of a second per guess on ordinary server hardware. That sounds trivial for one login attempt, and it is, but multiply it across a database of millions of stolen hashes and it turns a cracking job that would finish over a weekend with SHA-256 into one that's still running years later. Scrypt and Argon2 go further and also demand a lot of memory per guess, which blunts the advantage of cheap, parallel GPU cracking rigs even more, since memory doesn't scale the way raw compute does.
This is also worth being upfront about with the hash generator linked below: it's a general-purpose MD5/SHA-1/SHA-256 tool, useful for understanding how hashing works or checksumming a file, but it is not what a real login system should use to store a password. A production system needs bcrypt, scrypt, or Argon2, not a raw SHA-256 hash of the raw input, no matter how tempting it is to reach for something already sitting in the standard library.
Salting, and how login actually verifies your password without decrypting anything
There's one more piece: salting. A salt is a random value generated uniquely for each password, then combined with the password before it's hashed. Every account gets its own salt, stored alongside the hash (it doesn't need to be secret, just unique). That's worth sitting with for a second, because it feels backward at first: the salt sits right next to the hash in the same database row, in plain view, and that's fine. Its job was never to be a secret. Its job was to make sure no two passwords, even identical ones, ever get run through the hash function the same way.
Salting solves two problems at once. First, it defeats rainbow tables, precomputed lookup tables that map common password hashes back to their plaintext, built once and reused against any unsalted database. A unique salt per user means an attacker has to redo that precomputation work for every single account, which is expensive enough to make rainbow tables useless. Second, it means two people with the identical password "password123" end up with completely different stored hashes, since each got mixed with a different salt before hashing. Without salting, an attacker scanning a leaked database could instantly spot every account sharing a password just by matching identical hashes.
So how does a login screen check your password without ever decrypting it? It doesn't decrypt anything. There's nothing to decrypt. When you type your password to log in, the server pulls your stored salt, combines it with what you just typed, runs it through the same slow hash function, and compares the result against the hash it has on file. If they match, you're in. If they don't, you're not. The server never "reads" your password in any meaningful sense; it just checks whether two fingerprints happen to line up. That's the whole mechanism, and it's why even the engineers who built the system can't tell you what your password is.
Try it
GlaeKit's Hash Generator lets you type text and see MD5, SHA-1, and SHA-256 hashes appear instantly, all computed locally in your browser. It's a good way to see hashing's one-way nature for yourself: change one character and watch the output scramble completely. Just remember: this demonstrates hash mechanics, it isn't the algorithm a real login system should use to store your password. That job belongs to bcrypt, scrypt, or Argon2.
Frequently asked questions
Why did a site just email me my actual password?
Because it stored your password in plaintext instead of hashing it. That's a serious security failure, not a convenience. A properly built site can't email you your old password back, because it never kept a copy of it, only the hash. Change that password right away, and change it anywhere else you used it too.
What's the difference between hashing and encryption?
Encryption is reversible: with the right key, you can decrypt ciphertext back into the original data. Hashing is one-way by design. There's no key and no reverse operation. Passwords should be hashed, not encrypted, because a hashed password can't be turned back into plaintext even by the company that stored it, which is exactly the property you want.
Why is bcrypt better than SHA-256 for storing passwords?
SHA-256 is fast by design, which is great for checksums but terrible for passwords: it lets attackers try billions of guesses per second on cheap GPU hardware. Bcrypt is deliberately slow and its cost factor can be tuned upward as hardware improves, which shrinks an attacker's guessing rate to a small fraction of what SHA-256 allows against the same stolen database.
What is salting, and why does it matter?
A salt is a unique random value added to each password before it's hashed. It stops attackers from using precomputed rainbow tables to crack many passwords at once, and it means two identical passwords produce two completely different hashes, since each is mixed with its own salt.
If a hash can't be reversed, how does a site check my password at login?
It re-hashes what you just typed using your stored salt and the same algorithm, then compares that new hash against the one on file. A match means the password was correct. The site never decrypts anything or reads your password directly. It only ever compares fingerprints.