A SHA-256 hash is always 256 bits long. It produces that same-length result for hello, a password, or a multi-gigabyte backup archive. Change even one byte in the input, and the digest should look completely different. This fixed-size fingerprint is the basic idea behind cryptographic hashing.
Hashes help software detect changed data, let services verify passwords without storing them in readable form, and support signed code, version-control systems, and forensic integrity checks. They are useful security building blocks, yet they are often mistaken for encryption. The difference matters: confusing the two can lead to serious design errors.
What a hash function does
A hash function accepts data of almost any practical size and produces an output called a hash value, digest, or checksum. In cryptographic applications, the output serves as a distinctive digital fingerprint for the input.
For example, a program can calculate a SHA-256 digest for a downloaded installer. If that value matches a trusted digest published by the creator through a trustworthy channel, the downloaded file is very likely the intended release.
Cryptographic hash functions are designed around several important properties:
- Determinism: the same input always produces the same digest.
- Fixed output length: a given algorithm always emits the same number of bits.
- Preimage resistance: given only a digest, finding an input that produces it should be computationally infeasible.
- Second-preimage resistance: given one input, finding another input with the same digest should be infeasible.
- Collision resistance: finding any two distinct inputs with an identical digest should be infeasible.
- Avalanche effect: a tiny input change creates a substantially different-looking output.
The word “infeasible” is important. A hash has a finite output space, while possible inputs are effectively unlimited, so collisions must exist in theory. A secure algorithm makes deliberately finding a useful collision impractical with realistic computing resources.

Hashing is not encryption
Encryption is reversible for someone with the correct decryption key. A database field encrypted with an approved algorithm can be returned to plaintext when authorized software uses that key. Hashing is deliberately one-way: the normal hashing operation provides no way to reconstruct the original input.
| Technique | Primary purpose | Reversible? | Uses a secret key? |
|---|---|---|---|
| Encoding | Represent data in another format | Yes | No |
| Encryption | Keep data confidential | Yes, with the key | Yes |
| Cryptographic hashing | Check integrity or derive verification data | No | Not normally |
| HMAC | Verify integrity and authenticity between key holders | No | Yes |
Base64 causes similar confusion. It can represent binary data as text, but it provides no secrecy because anyone can decode it. A simple hash does not encrypt a document either. If a document must remain private, use modern authenticated encryption and protect the encryption keys.
Where hashes protect data
Password verification
Well-designed services do not store passwords as plain text. When a user creates an account, the service processes the password with a dedicated password-hashing function and stores the result along with the parameters needed for later verification. At login, it processes the submitted password in the same way and compares the result with the stored verifier.
A database breach therefore does not automatically reveal every password in readable form. Risk remains, because an attacker may try likely passwords offline. Password hashing makes each guess deliberately expensive, giving users and defenders more protection.
Suitable password-hashing algorithms include Argon2id, bcrypt, scrypt, and PBKDF2 where a suitable modern alternative is unavailable. Fast general-purpose hashes such as MD5, SHA-1, SHA-256, and SHA-512 are not sufficient on their own for password storage. They were designed for speed, and that speed allows more password guesses.
File and backup integrity
Hashes are useful for checking files after a transfer, download, archive operation, or copy to removable media. Developers may hash release packages, administrators may compare backup hashes before and after a move, and investigators may record evidence hashes to show that a working copy has not changed.
A matching hash proves integrity only against a trusted reference digest. It does not prove where a file came from. If an attacker can replace both the file and the webpage or message that displays its hash, the values can still match. Digital signatures, authenticated distribution channels, and independently verified release keys help close that authenticity gap.
Version control and content identification
Systems such as Git use hashes to identify objects and connect project history. A commit refers to related content through hash-based identifiers, which makes unintended changes visible in the repository structure. Modern Git installations can use SHA-256 object formats, while older repositories commonly use SHA-1. For beginners, the key point is that a hash identifies particular content; it does not prove an author’s intent or establish that a repository is trustworthy.
Hashing can also support deduplication. When a storage system recognizes identical content fingerprints, it may avoid storing duplicate copies. That approach needs careful design: hashes should not be the sole authorization mechanism, especially where users can deliberately submit inputs.
Salts, peppers, and slow password hashes
A secure password-storage design requires more than choosing a hash algorithm. Three related controls are especially important:
- Salt: a unique, randomly generated value combined with each password before hashing. It is stored with the resulting verifier and does not need to be secret.
- Work factor: a configurable cost that makes verification consume meaningful resources. For Argon2id, this includes memory, time, and parallelism settings.
- Pepper: an optional separate secret kept outside the password database, often in protected configuration or a secrets-management system.
Unique salts prevent two users with the same password from receiving identical stored hashes. They also make large precomputed tables for unsalted password hashes ineffective. A salt does not replace a strong password policy, rate limiting, multi-factor authentication, or secure account recovery.
A pepper can provide defense in depth, but it creates operational responsibilities. If it is lost, password verifiers that depend on it may no longer work. If it is exposed, it needs rotation through a planned migration process. New developers are better served by a well-maintained authentication library than by a home-grown password-storage scheme.
Hash algorithms: current choices and legacy risks
The right algorithm depends on the job. SHA-256 and SHA-512/256 remain common choices for general integrity work. SHA-3 is a separate standardized family with a different internal construction. BLAKE2 and BLAKE3 are modern fast hashes used in many engineering contexts, though protocol compatibility often decides the practical option.
MD5 and SHA-1 are legacy algorithms with known collision weaknesses. Do not use them for security-sensitive integrity checks, digital signatures, certificate-related uses, or new designs. Older software may still show these values for non-adversarial accidental-corruption checks, but that is not a reason to repeat the practice in a new project.
For password storage, choose a password-hashing function instead of trying to improve SHA-256 with custom steps. Established password-hashing primitives are designed to resist high-volume guessing through tunable cost and, in some cases, memory-hard behavior.
HMAC: when integrity also needs authenticity
Anyone can calculate a plain hash. That helps detect accidental damage, but it cannot prove who created a message. A Hash-based Message Authentication Code, usually called HMAC, combines a cryptographic hash with a shared secret key.
Consider an internal service sending a webhook payload to another service. The sender calculates an HMAC over the exact payload with their shared secret. The receiving service calculates the HMAC independently and compares the values with a constant-time comparison function. A valid match indicates that the message was not altered and came from a party with access to the secret.
HMAC does not encrypt the payload. Sensitive content still needs encryption in transit, usually TLS, and possibly encryption at rest. Receivers should also check timestamps or unique event identifiers to reduce replay risk, because a correctly signed old message can still be old.

Safe ways to verify a downloaded file
Calculating a digest is simple, but trust begins before you run the command. Obtain the expected digest from an authenticated source controlled by the publisher, preferably with a verified digital signature when one is available. Do not trust a hash sent in an unrelated message or copied from an untrusted repost.
- Download the file from the official or otherwise authorized distribution channel.
- Find the publisher’s expected SHA-256 value through a separate trusted path when practical.
- Calculate the digest locally with an operating-system tool or trusted development environment.
- Compare the complete values, not only the first few characters.
- If they differ, delete the file and download it again. Do not install or execute it while the mismatch remains unresolved.
On Linux, sha256sum filename is commonly available. On macOS, shasum -a 256 filename calculates the same kind of digest. Windows PowerShell provides Get-FileHash filename -Algorithm SHA256. These are defensive verification tools for files you are authorized to handle, and the result is useful only when the expected digest itself is trustworthy.
Common mistakes that weaken hashing
Several shortcuts can turn a sound cryptographic primitive into weak protection:
- Storing unsalted, fast password hashes.
- Using MD5 or SHA-1 in new security features.
- Writing a custom construction such as
hash(password + secret)instead of using an established password-hashing library or HMAC where appropriate. - Comparing secret-derived values with ordinary string comparison when the language offers a constant-time comparison utility.
- Trusting a checksum delivered through the same compromised channel as the file.
- Assuming a hash hides sensitive input. A hash of a predictable identifier may be guessable, and hashes are not anonymous data by default.
Logging creates a quieter version of that final problem. Do not log password values, password hashes, access tokens, session cookies, or HMAC secrets. Hashes used only as non-secret file identifiers may be acceptable in logs, although their context can still reveal information about known files or user activity.
A practical Java example for integrity checking
Java provides the MessageDigest API for general hashes. This pattern calculates a SHA-256 digest for bytes already held in memory. It is appropriate for integrity-related tasks, not password storage.
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(data);
String hex = HexFormat.of().formatHex(hash);
For a large file, process data as a stream instead of loading the entire file into memory: repeatedly pass chunks to digest.update(buffer, 0, bytesRead), then call digest.digest() after the final chunk. Do not use MessageDigest as a substitute for password hashing. Use a vetted Argon2id, bcrypt, scrypt, or PBKDF2 implementation with a unique random salt and carefully chosen parameters. As a first exercise, hash a small file, change one character, hash it again, and compare the full SHA-256 values.
