What a hash function is
A cryptographic hash function takes input of any size and produces a fixed-size output (the 'digest' or 'hash'). The same input always produces the same output, but the output reveals nothing useful about the input. A good cryptographic hash has three core properties: pre-image resistance (you cannot find an input that produces a given hash), second pre-image resistance (you cannot find a second input that produces the same hash as a known input), and collision resistance (you cannot find any two inputs that produce the same hash).
Common use cases for hashes
- File integrity verification — comparing downloaded files against published checksums.
- Digital signatures — sign the hash, not the document, because the signing operation is slow.
- Deduplication — using a hash as a content address (e.g., Git's object store).
- Caching — using the hash of a request as a cache key.
- Password storage — but only with a password-specific hash like Argon2 or bcrypt (see below).
- Proof-of-work and blockchain — relies on the difficulty of finding inputs with specific output properties.
SHA-256
SHA-256 produces a 256-bit (32-byte, 64 hexadecimal characters) digest. It is part of the SHA-2 family designed by the NSA and standardized by NIST. As of today, SHA-256 has no known practical attacks, and finding a collision is computationally infeasible. It is the default choice for new applications that need a fast cryptographic hash: TLS certificates, Git (newer versions), Bitcoin, and most file integrity workflows.
SHA-1
SHA-1 produces a 160-bit (20-byte, 40 hexadecimal characters) digest. It was widely used in the 2000s, but practical collision attacks were demonstrated in 2017 (the 'SHAttered' attack). SHA-1 should not be used for any new application that requires collision resistance — that includes digital signatures, certificates, and any 'is this file the same' check where an attacker could supply the file. SHA-1 remains acceptable for non-adversarial integrity checks where collisions are merely accidental risks (such as Git's legacy object IDs).
MD5
MD5 produces a 128-bit (16-byte, 32 hexadecimal characters) digest. It is fast and ubiquitous, but it is completely broken: collisions can be found in seconds on commodity hardware. MD5 should never be used in any security context. It remains acceptable only as a fingerprint for non-security purposes — for example, checking whether a file has been corrupted in transit on a trusted internal network.
Why hashes are not encryption
Hash functions are one-way. Once you hash a value, you cannot recover the original from the hash. This is what makes them useful for password storage and integrity verification, but it also means you cannot 'unhash' a SHA-256. If you see code that claims to 'decrypt' an MD5 or SHA-256, it is either using a precomputed lookup table (a 'rainbow table') for very short or common inputs, or it is lying.
Password hashing is different
General-purpose hashes like SHA-256 are designed to be fast. That speed is a security liability for passwords: an attacker who steals your hash database can try billions of passwords per second on a single GPU. Password hashing functions are deliberately slow and memory-hard. Use Argon2id (current best practice), bcrypt (still widely accepted), or scrypt. Never store passwords with SHA-256, SHA-1, or MD5, even with a salt — salting prevents rainbow tables but does not slow down brute force.
Salts and peppers
A salt is a unique random value mixed into the password before hashing. Each user gets their own salt, stored alongside the hash. This prevents an attacker from precomputing hashes for common passwords and looking up matches in bulk. A pepper is a single secret value added to all passwords, stored separately from the database (e.g., in an HSM or environment variable). Together, salt and pepper substantially increase the cost of an offline attack.
Choosing the right hash for the job
- File integrity, certificates, content addressing: SHA-256 (or BLAKE3 if speed matters and the library is available).
- Non-security fingerprints, legacy interop: SHA-1 or MD5 are acceptable but document the choice.
- Password storage: Argon2id, bcrypt, or scrypt. Never a general-purpose hash.
- Message authentication: HMAC-SHA-256 (not SHA-256 alone).