A hash function takes an input of any size and produces a fixed-size output called a hash digest. No matter whether you hash a single character or an entire database, the output length stays the same. The same input always produces the same output, but even a tiny change in the input — flipping one bit — produces a completely different hash.
This property, called the avalanche effect, is crucial for security. It means attackers cannot predict how a small modification to input will affect the output, making brute-force attempts far less efficient. Cryptographic hash functions are designed to be one-way: given a hash, it should be computationally infeasible to reconstruct the original input.
The three fundamental properties every cryptographic hash function must satisfy:
h, it should be impractical to find any input m such that hash(m) = h.m1, it should be impractical to find a different m2 with the same hash.MD5 produces a 128-bit digest and was widely used for years, but it is now considered broken for security purposes. In 2004, researchers demonstrated practical collision attacks against MD5, and in 2008 they used MD5 collisions to create a rogue CA certificate. MD5 is still useful for non-security tasks like checksumming file downloads, but should never be used for passwords or digital signatures.
SHA-256 is part of the SHA-2 family and produces a 256-bit digest. It is currently the standard for most security applications — TLS certificates, code signing, blockchain mining, and password hashing all rely on SHA-2 variants. As of 2025, no practical collision attacks exist against SHA-256.
SHA-3 (Keccak) was introduced as an alternative to SHA-2 with a fundamentally different internal structure. While not yet as widely deployed, it provides a hedge against any future breakthrough in SHA-2 cryptanalysis. For most applications today, SHA-256 remains the go-to choice.
Storing passwords in plaintext is one of the most dangerous practices in computing. If a database is compromised, attackers immediately have every user's password. Hashing transforms each password into a fixed-length digest — the original password never needs to be stored at all.
When a user logs in, the system hashes their submitted password and compares it against the stored hash. If the hashes match, the password is correct. The system never sees or stores the actual password at any point after the initial hash computation.
However, simple hashing isn't enough. Attackers use pre-computed tables called rainbow tables that contain billions of hash-to-password mappings. Even GPU-based brute force can crack common hash algorithms at staggering speeds — MD5 at billions per second, SHA-256 at hundreds of millions per second. This is where salting comes in.
A salt is a unique random value generated for each password. Instead of hashing hash(password), the system stores hash(salt + password). The salt is stored alongside the hash — it doesn't need to be secret. Its purpose is to ensure that two identical passwords produce different hashes, rendering rainbow tables and pre-computed attacks useless.
Modern password hashing goes further with key derivation functions (KDFs) designed to be deliberately slow:
Never roll your own password hashing. Use established libraries (like password_hash() in PHP or bcrypt in Node.js) that handle salting, cost factors, and algorithm selection automatically.
Hashing has many applications beyond authentication:
Whether you're verifying a download, securing a login, or building a blockchain, hashing is the invisible mechanism that makes integrity and authenticity possible.