How Passwords Are Actually Stored
When you set a password on any modern website, the site doesn't store your password. It can't — or at least, it shouldn't. What it stores is something derived from your password: a value that can verify your password when you log in, but cannot be reversed to reveal it. This is hashing, and it's one of the most important ideas in modern security.
Why Not Store the Password Directly?
If a database stores plaintext passwords, a single breach exposes every user's password to an attacker. Not just the accounts on that site — since most people reuse passwords, the breach becomes leverage for attacks on other sites too. Adobe's 2013 breach leaked 38 million customers' passwords in plaintext. Credential stuffing attacks using that data affected users across the internet for years afterward.
Encryption isn't the answer either. Encryption is reversible — if you have the key, you can decrypt. If the key is stored alongside the database, an attacker who gets both can recover all passwords. What's needed is a one-way transformation.
What Hashing Does
A hash function takes an input of any size and produces a fixed-size output — typically a hex string. The same input always produces the same output, but there's no mathematical way to go from the output back to the input. This is the one-way property that makes hashing useful for passwords.
When you log in, the site hashes the password you typed and compares it to the stored hash. If they match, you're authenticated. The site never needs to know your actual password — only whether the hash of what you typed matches what's stored.
The MD5 and SHA-1 Mistake
Early web applications used MD5 or SHA-1 to hash passwords. These are cryptographic hash functions — fast, deterministic, widely available. The problem: they're fast in both directions. An attacker with a stolen hash database can run billions of hash computations per second on modern hardware. Password cracking rigs using GPUs can compute 10 billion MD5 hashes per second.
A fast hash function is exactly the wrong tool for password storage. You want the hashing to be slow — slow enough that computing a billion hashes becomes computationally prohibitive, while normal login verification remains fast enough to be invisible to the user.
The Role of Salts
Before modern slow hashing, security-conscious developers added salts — random values appended to passwords before hashing. This defeats precomputation attacks (rainbow tables): an attacker can't simply look up a hash in a precomputed table, because the salt makes every hash unique even for identical passwords.
Salts need to be unique per user and stored alongside the hash. They don't need to be secret. Their purpose is to make mass cracking expensive, not to add secrecy.
bcrypt, scrypt, and Argon2
Modern password hashing algorithms are designed to be slow and memory-intensive. bcrypt, introduced in 1999, has a configurable work factor — increasing it doubles the computation time. This allows systems to remain secure as hardware gets faster: just increase the work factor. scrypt adds a memory-hardness parameter, making it more resistant to hardware-optimized (ASIC) attacks. Argon2 won the Password Hashing Competition in 2015 and is the current recommendation for new systems.
These algorithms do what MD5 never could: make cracking physically expensive even when an attacker has the hash database and unlimited computation.
Need to generate or verify a hash for testing, debugging, or understanding a security system? DevToolkit's Hash Generator computes MD5, SHA-1, SHA-256, and SHA-512 hashes instantly — no server, all in your browser.