Lesson 1 of 7 · 9 min read
Hashes, MACs and Digital Signatures
In this lesson
TL;DR: A hash (such as SHA-256) is a fingerprint anyone can compute, so it detects accidental change but not an attacker who replaces both the data and its hash. A MAC (such as HMAC-SHA256) mixes in a secret key, so only key holders can produce or check a valid tag: integrity and authenticity between parties that share the key. A digital signature (such as Ed25519) is made with a private key and checked with a public key, so anyone can verify it and only the key holder could have made it, which also gives non-repudiation.
Before you read
Pick an answer before you read further. The lesson below explains it, and guessing first, right or wrong, helps the explanation stay with you.
1A download page lists a file and its SHA-256 hash, both served from the same web server. If an attacker takes over the server, does the hash protect users?
Hashes: fingerprints anyone can make
A cryptographic hash function maps input of any size to a fixed-size output, 256 bits for SHA-256. Three properties make it useful for security:
- Preimage resistance: given a hash, you cannot find an input that produces it.
- Second-preimage resistance: given an input, you cannot find a different input with the same hash.
- Collision resistance: you cannot find any two inputs with the same hash.
"Cannot" means "not with any feasible amount of computation". These properties fail for broken functions: practical collisions exist for MD5 and, since the SHAttered result in 2017, for SHA-1. Use the SHA-2 family (SHA-256, SHA-512) or SHA-3.
What a hash does not have is a key. Anyone can compute the hash of anything, which means a hash detects change only when the hash itself is protected. Package managers, model hubs and container registries use hashes this way: a lockfile or a signed manifest records the expected hash, and the downloader checks the file against it. The trust lives in whatever protects the record of the hash.
Hashes are also the wrong tool for passwords. They are designed to be fast, which helps an attacker test billions of guesses. Password storage uses deliberately slow functions such as Argon2id, covered in the password storage question.
How much security a hash gives: the birthday bound
An n-bit hash offers about 2^n work against preimages but only about 2^(n/2) against collisions, because an attacker looking for any two matching inputs benefits from the birthday paradox: among k random values, the chance that two share an n-bit hash reaches 50% around k ≈ 1.18 × 2^(n/2).
| Output size | Values until a 50% chance of some collision | Where you meet it |
|---|---|---|
| 32 bits | about 77,000 | Short random IDs, CRC32 checksums |
| 64 bits | about 5.1 billion | Truncated hashes used as cache keys or dedup IDs |
| 128 bits | about 2.2 × 10^19 | MD5's nominal size (MD5 is broken far below this) |
| 256 bits | about 4.0 × 10^38 | SHA-256: collision resistance of 2^128 |
The engineering lessons: a 32-bit ID space collides in a table of tens of thousands of rows, so do not use short hashes as unique keys; a truncated 64-bit hash is fine for a cache but not for anything an attacker can choose inputs for; and SHA-256's 128-bit collision level is why it is the default.
What "broken" looked like in practice
Collision attacks moved from papers to forged trust anchors:
- MD5. In 2008, researchers used a chosen-prefix MD5 collision to create a rogue CA certificate. In 2012 the Flame malware used another chosen-prefix MD5 collision to forge a Microsoft code-signing certificate, so its updates looked like they came from Microsoft.
- SHA-1. The SHAttered collision (Google and CWI, 2017) produced two different PDF files with the same SHA-1 hash after about 2^63 SHA-1 computations. In 2020, "SHA-1 is a Shambles" demonstrated a chosen-prefix collision, the more dangerous kind, where the attacker picks both starting documents, at a cost the authors estimated in the tens of thousands of dollars of rented GPU time.
A chosen-prefix collision is what an attacker needs to forge certificates or signed documents: they get one harmless document signed and the signature transfers to a malicious one with the same hash. That is why signature schemes, certificate authorities and Git's object model have moved or are moving off SHA-1 even though nobody has found a preimage attack on it.
MACs: integrity between key holders
A message authentication code combines a message with a secret key to produce a tag. Without the key, an attacker cannot produce a valid tag for a modified message. HMAC, standardised in RFC 2104, is the common construction, usually with SHA-256.
The most familiar use is webhook verification. A payment provider and your server share a secret. The provider sends each event with an HMAC of its body; your server recomputes the HMAC with the same secret and rejects the event if the tags differ. An attacker who can reach your endpoint but does not know the secret cannot forge an event.
Two details matter in practice:
- Compare tags in constant time. A comparison that stops at the first differing byte leaks, through timing, how much of a forged tag was right. Libraries provide constant-time comparison functions; use them.
- Use HMAC rather than inventing a construction. Computing
SHA-256(key || message)is vulnerable to length extension: given one valid tag, an attacker can compute a valid tag for the message with data appended, without knowing the key. HMAC's nested structure prevents this.
The limitation of a MAC is in its key. Both sides hold the same secret, so either could have produced any tag. A MAC convinces the parties who share the key; it cannot prove to a third party which of them sent a message.
Signatures: anyone can verify, only one can sign
A digital signature scheme uses a key pair. The private key, held by one party, produces signatures. The public key, which can be published, verifies them. Ed25519, ECDSA over P-256 and RSA-PSS are common choices.
Because only the holder of the private key can sign, a valid signature tells any verifier both that the message is unchanged and which key produced it. That is what makes signatures the basis of software and model signing, TLS certificates and signed tokens. It also provides non-repudiation, within limits: the signer cannot plausibly claim someone else produced it, unless the private key was stolen.
Signatures move the hard problem rather than removing it. A verifier needs the right public key, delivered through a channel the attacker cannot tamper with. If an attacker can swap the public key you trust, every signature check passes for their content. Distributing and vouching for public keys is the job of PKI and certificate chains and of newer systems such as Sigstore.
Publisher
Sends file + check value
Attacker in the middle
Can change what is sent
Receiver
Checks before use
Hash only
The attacker swaps the file and recomputes the hash. The receiver's check passes, because a hash has no key.
How signatures fail in practice
The mathematics of modern signature schemes is rarely the weak point. These are:
- Nonce reuse in ECDSA. Every ECDSA signature needs a fresh secret random value. Two signatures made with the same value, or with a predictable one, let anyone who sees them solve for the private key with simple algebra. The 2010 break of the PlayStation 3's code-signing key happened because the same value was used for every signature. Ed25519 (RFC 8032) derives the per-signature value deterministically from the key and the message, which removes the random number generator from the risk; RFC 6979 does the same for ECDSA.
- Verifying the wrong key. A signature proves the holder of a private key signed; it proves nothing about who that is unless the verifier obtained the public key through a trusted path: a certificate chain, a pinned key, a transparency log. "We verify the signature" with a public key fetched from the same place as the artifact proves nothing.
- Signing ambiguous bytes. If two different structures serialise to the same bytes, or a verifier re-serialises data before checking, a valid signature can be attached to content the signer never saw. Sign exact bytes, and include a context string or domain separator so a signature made for one purpose cannot be replayed for another.
- Letting the message choose the algorithm. Formats that carry an algorithm field, such as JSON Web Tokens, have been exploited by attackers switching the algorithm to "none" or to a MAC keyed with the public key. The verifier must decide the algorithm from its own configuration, never from the message. The identity track covers JWT validation in detail.
ECDSA with a weak random source
Sign message A
Sign message B
same nonce reused
Anyone solves for the key
Outcome, unsafe: Private key recovered
Two signatures with one nonce are enough.
Ed25519 or RFC 6979 ECDSA
Sign message A
Nonce derived from key and message
deterministic
Different message, different nonce
Outcome, safe: No RNG to get wrong
Same message gives the same signature; different messages never share a nonce.
Randomness as a single point of failure
ECDSA's security collapses if one secret per-signature value repeats or is predictable.
Choosing between them
| You need | Use | Because |
|---|---|---|
| Detect corruption, or check a file against a trusted list of hashes | Hash | No secret needed; trust comes from the list |
| Two systems you control, or a provider and you, verifying each other's messages | MAC | Fast, simple, one shared secret |
| Many verifiers, a public artifact, or proof of origin to third parties | Signature | Verifiers need only the public key; the signer alone can sign |
None of the three hides anything. Hashes, MACs and signatures protect integrity and authenticity, not confidentiality. Hiding content is encryption, covered in symmetric encryption and AEAD, which in modern designs includes a MAC-like tag of its own.
Why this matters for AI systems
Model files, datasets and agent tool packages are downloaded and loaded like any software, and the same three tools protect them. Hub downloads are checked against recorded hashes; model signing (for example the OpenSSF model signing specification, built on Sigstore, checked November 2026) lets a consumer verify who produced a set of weights; and webhooks between AI services and your backend are verified with HMACs. The questions to ask are always the same: who holds which key, and how did the verifier get the value it trusts?
Misconceptions interviewers listen for
- "Hashing is encryption." A hash cannot be reversed and has no key; encryption is reversible with a key.
- "A hash next to a download protects it." Only if the hash came through a channel the attacker cannot change.
- "SHA-1 is fine because nobody can reverse it." Collisions, not preimages, are what forge signatures and certificates.
- "A MAC gives non-repudiation." Both key holders can produce any tag.
- "We verify signatures, so the artifact is trustworthy." Only if the public key reached you through a trusted path and the algorithm is fixed by the verifier.
What if · interview follow-ups
Hold your answer as the constraints change
Your team distributes an internal ML model package and receives webhooks from a payment provider. The interviewer asks how each artifact's integrity is protected, changing one assumption at a time.
Start here
What if the model package is published with a SHA-256 checksum on the same web page as the download link?
Who can change the page?
Anyone who can replace the download can usually replace the checksum on the same page, so it only detects accidental corruption. To detect tampering, the expected hash must come through a channel the attacker cannot change: a signed manifest, a lockfile in your repository, or a transparency log entry.
Carry it forwardA hash protects integrity only as well as the channel that delivered the expected value.
Weak answerTreating a co-located checksum as tamper protection.
Constraint changes
What if the webhook signature is computed as SHA-256 of the secret followed by the body?
What can an attacker append to a message with a Merkle-Damgard hash?
SHA-256 of key then message is vulnerable to length extension: knowing one valid tag, an attacker can compute a valid tag for the same body with data appended, without the secret. Use HMAC-SHA256, which is built to prevent this, and compare tags in constant time.
Carry it forwardUse the standard keyed construction; ad hoc key-plus-hash designs have known breaks.
Weak answerAssuming any hash that includes a secret is a MAC.
Constraint changes
What if an auditor asks whether the provider can later deny sending a webhook?
Who else holds the HMAC key?
With an HMAC, your server holds the same key and could have produced any tag, so the tag cannot prove to a third party that the provider sent it. If you need proof of origin to others, the provider must sign with a private key only it holds, and you verify with its public key.
Carry it forwardShared keys give authenticity between the parties, not proof to anyone else.
Weak answerClaiming HMAC provides non-repudiation.
Constraint changes
What if the release pipeline signs models with ECDSA on a virtual machine whose random number generator is weak after boot?
What happens if two signatures share a nonce?
Reused or predictable nonces let anyone with two signatures recover the private key, which would let them sign malicious models as you. Use Ed25519 or deterministic ECDSA (RFC 6979), keep the signing key in an HSM or a managed signing service, and publish signatures to a transparency log so misuse is visible.
Carry it forwardRemove dependence on signing-time randomness, and keep the key where it cannot be copied.
Weak answerFocusing on curve choice while ignoring nonce generation.
Constraint changes
What if the downloader verifies the model signature using a public key it fetches from the same server as the model?
Who chose that public key?
An attacker who controls the server supplies their own key and their own signature, and verification passes. The public key, or the identity behind it, must be pinned in the downloader or obtained through a certificate chain or transparency log the attacker cannot control, such as keyless signing tied to your CI identity.
Carry it forwardA signature check is only as strong as the path by which the verifier got the public key.
Weak answerReporting the artifact as verified because the signature is mathematically valid.
Now defend it
As the defender, what would you monitor to know these integrity controls hold?
Verification failures at download and webhook endpoints, since a spike means tampering or misconfiguration; transparency-log entries for your signing identity, so unexpected signatures are noticed; key usage logs from the HSM or signing service; and any remaining use of MD5 or SHA-1 in signatures, certificates or manifests.
How this shows up in interviews
"What is the difference between hashing, encryption and signing?" is a near-universal screen question, and "what does a MAC prove that a hash does not?" is its follow-up. Strong candidates answer in terms of keys: no key, a shared key, a key pair. They add the practical traps without being asked: constant-time comparison, length extension, and the fact that a signature is only as trustworthy as the public key you verify it with.
Say it in 30 seconds: "A hash has no key, so anyone can recompute it; it proves integrity only if the hash itself comes from somewhere trusted. A MAC like HMAC uses a shared secret, so only key holders can make a valid tag, but either holder could have made it. A signature uses a private key to sign and a public key to verify, so anyone can check it and only one party could have produced it. None of them encrypts anything."
Check yourself
Say or write your answer first, then reveal. Explaining it from memory, in your own words, is the skill an interviewer is checking.
1A service verifies webhooks by computing HMAC-SHA256 of the body and comparing it to the header with ==. What is the risk, and the fix?
2Why would a model hub sign release manifests rather than just publishing SHA-256 hashes of each file?
3Roughly how many random 32-bit IDs can you generate before a collision is more likely than not?
4Why did ECDSA nonce reuse break the PlayStation 3's code-signing key?