Part II: Proof · Chapter 5
Hashes and fingerprints
In one sentence
A cryptographic hash turns any data into a short, fixed-size fingerprint; any change gives a completely different fingerprint, and you cannot run it backwards to get the data.
Who is this for
Level: Beginner
On this page
The idea
- Beginner
Part I was about keeping secrets. Part II is about proof: proving that a message has not been changed, and later, proving who sent it. The first tool for that is the hash function.
A hash function takes any data, a word, a contract or a whole film, and turns it into a short value of fixed length called a hash or fingerprint. The most common one today, SHA-256, always gives 256 bits, written as 64 hexadecimal characters:
Pay Ken 10 coins → 04778255a716d056efbe13be2e2699e876d75551e8a8042aefbcfbf978293ffe
(This is the hash of the line as saved in a text file, which ends with an invisible line break. Hash the words without that line break and you get a completely different value, which is exactly the point.)
A good cryptographic hash has four properties:
- Same input, same hash. Anyone, anywhere, who hashes the same data gets the same result.
- A tiny change gives a completely different hash. Change “10” to “90” and the hash looks entirely new. This is called the avalanche effect.
- It only works one way. From the hash, nobody can work out the data. A hash is not a compressed copy; most of the information is thrown away.
- No two inputs with the same hash can be found. There are endless possible inputs and only a fixed number of hashes, so such pairs must exist. But finding one must be infeasible.
That makes a hash a fingerprint of the data. Compare two fingerprints instead of two huge files. Store a document’s hash today, and you can prove next year whether the document has changed.
Two things a hash is not:
- It is not encryption. There is no key, and there is nothing to decrypt. You cannot get the data back from a hash.
- It does not prove who made the data. Anyone can compute a hash. If an attacker changes a file and also controls the place where its hash is published, they simply publish the new hash. A hash proves integrity only when you got the hash from somewhere you trust. To prove who, you need a key: a MAC (below) or a digital signature.
How it really works
- Developer
- Expert
What exactly is SHA-256?
SHA-256 is part of the SHA-2 family, defined in FIPS 180-4. It splits the input into 512-bit blocks, pads the last one with the message length, and runs each block through a compression function that updates a 256-bit internal state. The final state is the hash. The input can be any length up to 2⁶⁴ − 1 bits.
| Algorithm | Output size | Block size | Collision strength | Status |
|---|---|---|---|---|
| MD5 | 128 bits | 512 bits | Broken | Never use for security |
| SHA-1 | 160 bits | 512 bits | Broken (less than 80 bits) | Being retired |
| SHA-256 | 256 bits | 512 bits | 128 bits | The usual choice |
| SHA-384 | 384 bits | 1,024 bits | 192 bits | Common in TLS and CAs |
| SHA-512 | 512 bits | 1,024 bits | 256 bits | Fast on 64-bit CPUs |
| SHA3-256 | 256 bits | 1,088 bits (rate) | 128 bits | Different design, same job |
Sizes come from FIPS 180-4 and FIPS 202 (SHA-3). Collision strengths come from Table 3 of NIST SP 800-57 Part 1, which notes that SHA-1 “has been demonstrated to provide less than 80 bits of security for digital signatures”. SHA-3 uses a completely different internal design, a “sponge”, so a future weakness in SHA-2 would not automatically carry over.
You can check any implementation against NIST’s test vector: the SHA-256 of the three bytes abc is ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad.
What does “secure” mean for a hash?
FIPS 180-4 calls its algorithms secure because “it is computationally infeasible 1) to find a message that corresponds to a given message digest, or 2) to find two different messages that produce the same message digest”. Cryptographers split that into three properties:
- Preimage resistance. Given a hash, you cannot find any input that produces it. For SHA-256 that would take about 2²⁵⁶ tries.
- Second-preimage resistance. Given one input, you cannot find a different input with the same hash.
- Collision resistance. You cannot find any two inputs with the same hash. Because of the “birthday paradox”, this is easier than a preimage: about 2¹²⁸ tries for a 256-bit hash. That is why a hash’s security level is usually half its output size.
Why did MD5 and SHA-1 fall?
Both were broken by collision attacks: researchers found ways to build two different inputs with the same hash far faster than the birthday bound.
- MD5. Collisions became practical in the 2000s. RFC 6151 says it is “not prudent to use MD5 when collision resistance is required” and that MD5 “must not be used for digital signatures”. A collision was once used to forge a certificate authority certificate; see famous failures.
- SHA-1. February 2017: the first public SHA-1 collision, two different PDF files with the same SHA-1 hash. NIST says SHA-1 should be phased out by 31 December 2030. For the public web, the CA/Browser Forum set a final date too: from 15 September 2026, publicly trusted CAs must stop all remaining use of SHA-1 in TLS certificates and CRLs.
Why do collisions matter so much? Because a digital signature signs the hash of a document, not the document itself. If an attacker can make two documents with the same hash, an innocent one and a harmful one, a signature on the first is also valid for the second. Collisions are an attack on signatures, which is why certificate signatures were among the first uses moved from SHA-1 to SHA-256.
Hash, MAC or signature: which proves what?
| Tool | Key | What it proves | Who can check |
|---|---|---|---|
| Hash (SHA-256) | None | The data matches a hash you already trust | Anyone |
| MAC (HMAC-SHA-256) | One shared secret key | The data was made or approved by a holder of the key, and not changed | Only key holders |
| Digital signature | Private key signs, public key verifies | The data was signed by the holder of the private key, and not changed | Anyone with the public key |
A HMAC mixes a secret key into the hash (RFC 2104, FIPS 198-1). Without the key, nobody can compute a valid HMAC for changed data. Webhooks, API request signing and the TLS key schedule all use HMAC. But every holder of the key can create valid HMACs, so it cannot prove which holder made one. Signatures fix that.
Where do fingerprints appear in PKI?
- Certificate fingerprints. The SHA-256 fingerprint of a certificate is simply the hash of its DER-encoded bytes. It is not a field inside the certificate; your tools compute it. Different hash algorithms give different fingerprints for the same certificate.
- Key identifiers. The Subject Key Identifier extension is often a hash of the public key; RFC 5280, section 4.2.1.2 describes using the SHA-1 hash of the key. Here SHA-1 is only a label, not a security check.
- SSH host and user keys.
SHA256:…fingerprints are hashes of the public key, used to check by eye that a key is the right one (see binding identity). - Signatures. Most signature algorithms in TLS name their hash:
ecdsa_secp256r1_sha256,rsa_pss_rsae_sha256and so on. (Ed25519 has SHA-512 built in.)
Why are plain hashes wrong for passwords?
SHA-256 is designed to be fast. That is bad for passwords, because an attacker who steals a database of password hashes can test enormous numbers of guesses per second. Password storage needs a salted, deliberately slow “password hashing scheme”. NIST SP 800-63B-4 (section 3.1.1.2) says passwords “SHALL be salted and hashed using a suitable password hashing scheme”. Common choices are PBKDF2 (SP 800-132) and Argon2 (RFC 9106).
At work
- Developer
- IT ops
Hash a file
On Linux and in Git Bash on Windows (on macOS, shasum -a 256 does the same):
sha256sum decree.txt decree2.txt
04778255a716d056efbe13be2e2699e876d75551e8a8042aefbcfbf978293ffe *decree.txt
030bb2a254bf90a8a7d321e405cc7175ed501743cdcb69b62464d9b953e8fa7a *decree2.txt
The two files differ in one character (“10” and “90”). (On Linux you see two spaces before the file name instead of *; the star only marks “binary mode”.) OpenSSL gives the same hash:
openssl dgst -sha256 decree.txt
SHA2-256(decree.txt)= 04778255a716d056efbe13be2e2699e876d75551e8a8042aefbcfbf978293ffe
In PowerShell, use Get-FileHash, which uses SHA-256 by default and prints upper-case hex:
Get-FileHash .\decree.txt -Algorithm SHA256 | Format-List Algorithm, Hash
Algorithm : SHA256
Hash : 04778255A716D056EFBE13BE2E2699E876D75551E8A8042AEFBCFBF978293FFE
Check a download against a checksum file
Many projects publish a file of hashes next to their downloads. sha256sum -c recomputes each hash and compares:
sha256sum -c SHA256SUMS
decree.txt: OK
After someone changes the file:
decree.txt: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
Remember the limit: this only proves the file matches the checksum file. If an attacker can replace both, the check passes. Get the checksum over a channel you trust, or better, check a signature on the checksum file, which projects often publish too. The next chapter shows how.
Look at a certificate’s fingerprint
A certificate’s fingerprint is the hash of its DER bytes, so you get the same value two ways (certificate for rfc-editor.org, fetched on 20 October 2026; yours will differ after renewal):
openssl x509 -in site.pem -noout -subject -fingerprint -sha256
openssl x509 -in site.pem -outform DER | sha256sum
subject=CN=rfc-editor.org
sha256 Fingerprint=A7:C1:67:07:E3:2A:FD:F4:E4:F7:0F:62:C1:40:BC:DF:61:C6:C5:01:EF:5D:0B:5D:5F:0A:78:4D:CC:14:0D:BF
a7c16707e32afdf4e4f70f62c140bcdf61c6c501ef5d0b5d5f0a784dcc140dbf *-
Same 32 bytes, once with colons and once without. Fingerprints are how admins confirm “this is exactly the certificate I meant” in a support ticket, a pinning configuration or an allow-list. Try it in the decoder: open the sample certificate and find its SHA-256 fingerprint.
Use HMAC when two systems share a secret
Webhook senders often attach an HMAC so the receiver can check the message came from a key holder and was not changed:
openssl dgst -sha256 -hmac "a shared secret" decree.txt
HMAC-SHA2-256(decree.txt)= 06674d1a26029d6b325ee28a673e8152d7f663193e9a008f1644ed182edfad06
In production, use a long random key (openssl rand -hex 32) rather than a phrase, and compare HMACs in code with a constant-time comparison function from your library, not with a plain string comparison.
What to fix when you find it
- MD5 or SHA-1 in a security role. Signatures, certificates, integrity checks against attackers and password storage: move to SHA-256 or better. MD5 is still fine for spotting accidental corruption, never against an attacker.
- Fast hashes for passwords.
sha256(password)ormd5(password)in a user table is a finding. Migrate to Argon2 or PBKDF2 with a salt, re-hashing each password at the user’s next login. - Checksums published next to the file they protect. Add a signature, or publish the hash somewhere separate that you control.
Common mistakes
- “Hashing is a kind of encryption.” There is no key and nothing to decrypt. A hash cannot be turned back into the data. “Cracking” a password hash means guessing inputs until one matches, which is why weak passwords fall.
- “A matching hash proves who sent the file.” Anyone can compute a hash. It proves the file matches a hash you trust, nothing more. Proving who needs an HMAC key or a digital signature.
- “Every file has a unique hash.” Collisions must exist, because there are more possible files than hashes. A good hash makes them infeasible to find. MD5 and SHA-1 lost that property.
- “Any hash will do for passwords.” Fast, unsalted hashes let attackers test guesses at high speed. Use a password hashing scheme with a salt.
- “The fingerprint is printed inside the certificate.” It is computed by whoever looks at the certificate. SHA-1 and SHA-256 fingerprints of the same certificate are different strings.
Why it matters to the business
- Leader
Check yourself
Ken changes a single character in a decree and computes its SHA-256 hash again. How does the new hash compare with the old one?
RightNot quite The answer is B: About half of all its bits are different, with no visible pattern
- What happened
- Changing '10' to '90' flipped one input bit and changed 121 of the 256 output bits.
- Why
- Hash functions are designed so that every input bit affects every output bit. This avalanche effect makes it impossible to tell how similar two inputs were from their hashes.
- The rule
- Any change to the data, however small, gives a completely different hash.
Show answer
Answer B About half of all its bits are different, with no visible pattern
- What happened
- Changing '10' to '90' flipped one input bit and changed 121 of the 256 output bits.
- Why
- Hash functions are designed so that every input bit affects every output bit. This avalanche effect makes it impossible to tell how similar two inputs were from their hashes.
- The rule
- Any change to the data, however small, gives a completely different hash.
A download page shows a file and its SHA-256 hash side by side. An attacker takes over the page and swaps the file. Does checking the hash protect you?
RightNot quite The answer is B: No: the attacker can publish the new file's hash too, so the hash must come from a source you trust or carry a signature
- What happened
- Both the file and its hash came from the same place the attacker controls.
- Why
- A hash has no key. Anyone can compute the right hash for the malicious file and publish it.
- The rule
- A hash proves integrity only against a hash you already trust. To prove who published something, check a signature.
Show answer
Answer B No: the attacker can publish the new file's hash too, so the hash must come from a source you trust or carry a signature
- What happened
- Both the file and its hash came from the same place the attacker controls.
- Why
- A hash has no key. Anyone can compute the right hash for the malicious file and publish it.
- The rule
- A hash proves integrity only against a hash you already trust. To prove who published something, check a signature.
A team says: 'Our passwords are safe because we store them as SHA-256 hashes, so they are encrypted.' What is the best response?
RightNot quite The answer is B: A hash is not encryption, and a fast unsalted hash lets attackers test guesses quickly; use a salted password hashing scheme such as Argon2 or PBKDF2
- What happened
- The team confused hashing with encryption and picked a hash built for speed.
- Why
- Stolen password hashes are attacked by guessing passwords and hashing each guess. A fast hash makes each guess cheap; a salted, slow scheme makes every guess expensive and stops precomputed tables.
- The rule
- Hashes are one-way, not encryption. Store passwords with a salted, deliberately slow password hashing scheme.
Show answer
Answer B A hash is not encryption, and a fast unsalted hash lets attackers test guesses quickly; use a salted password hashing scheme such as Argon2 or PBKDF2
- What happened
- The team confused hashing with encryption and picked a hash built for speed.
- Why
- Stolen password hashes are attacked by guessing passwords and hashing each guess. A fast hash makes each guess cheap; a salted, slow scheme makes every guess expensive and stops precomputed tables.
- The rule
- Hashes are one-way, not encryption. Store passwords with a salted, deliberately slow password hashing scheme.
Go deeper
- FIPS 180-4: Secure Hash Standard: SHA-1 and the SHA-2 family, with their sizes and padding.
- FIPS 202: SHA-3 Standard: the sponge-based alternative to SHA-2.
- NIST: NIST retires SHA-1: the announcement and the transition date.
- RFC 6151 and RFC 6194: the IETF’s security considerations for MD5 and SHA-1.
- RFC 2104: HMAC, the keyed hash used across the internet.
- NIST SP 800-63B-4: how to store passwords (section 3.1.1.2).
- OpenSSL
dgstdocumentation: hashing, HMAC and signing from the command line.
Short on time? The crash course covers this chapter and the next in Lesson 3: Fingerprints and signatures.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.