HMAC-SHA-1: Still Sound Even Though SHA-1 Collisions Are Not
HMAC-SHA-1 is a keyed authentication tag of 160 bits built on SHA-1. The published SHA-1 collision attacks do not break it, because HMAC's security rests on the compression function behaving pseudorandomly rather than on collision resistance.
At a glance
- Tag size
- 160 bits
- Hex characters
- 40
- Inner hash block size
- 64 bytes. Keys longer than 64 bytes are hashed down first
- Standard
- RFC 2104 for HMAC, FIPS 198-1 for the keyed hash, SHA-1 itself from FIPS 180-4
- Affected by SHA-1 collisions
- No. Collision resistance is not what HMAC relies on
- Safe for password storage
- No. Use a memory-hard password hash such as Argon2id, scrypt or bcrypt
- Available in the generator
- Yes, once you fill in the secret field
In detail
HMAC wraps a hash in two keyed passes: the key is padded to the block size, XORed with two different constants, and the message is hashed inside the first and the result hashed again inside the second. That structure is what makes it safe with a hash whose collision resistance has failed. An attacker who can produce two colliding SHA-1 messages gains nothing, because they cannot evaluate the keyed function without the key.
This is why standards bodies deprecated SHA-1 signatures years before they came anywhere near deprecating HMAC-SHA-1. The relevant NIST guidance still permits HMAC-SHA-1 for authentication while forbidding SHA-1 for signature generation. Treating them as one decision, and ripping out working HMAC-SHA-1 because a scanner matched on the string SHA1, is a common and expensive mistake.
You meet it most often in one-time passwords. HOTP as defined in RFC 4226 and TOTP in RFC 6238 both default to HMAC-SHA-1 over a counter or a time step, which is why almost every authenticator app is doing HMAC-SHA-1 many times a day. OAuth 1.0a request signing and the retired AWS Signature Version 2 also used it, and plenty of internal webhook systems still do.
Where it is genuinely wrong is in new designs that have a free choice. There is no benefit to a 160 bit tag over a 256 bit one, the performance difference is irrelevant at message sizes anyone actually authenticates, and you will spend the next decade explaining the choice to auditors. Use HMAC-SHA-256 for anything new, and keep HMAC-SHA-1 only where a counterparty protocol demands it.
It is not a password hash, and the temptation here is specific: some systems store HMAC(pepper, password) and call it hardened. A server side pepper does help if the database leaks but the key does not, yet it does nothing about attack throughput once the key leaks too. The password itself still needs Argon2id, scrypt or bcrypt underneath. ToolBox does not offer a password hashing tool.
Examples
key: "Jefe"
data: "what do ya want for nothing?"
HMAC-SHA-1 = effcdf6ae5eb2fa2d27416d5f184df9c259a7c79Use this to confirm any HMAC implementation is keying and padding correctly before you trust it.
key: "key"
data: "The quick brown fox jumps over the lazy dog"
HMAC-SHA-1 = de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9Things that catch people out
- A tag of 40 hex characters looks exactly like a bare SHA-1 digest, and the generator's Verify tab cannot tell them apart from length. Label the field in your own systems, because 'is this a hash or a tag' has caused real integration outages.
- HMAC keys longer than 64 bytes are hashed down to 20 bytes before use. A 200 character 'extra secure' key therefore carries no more entropy into the function than a 64 byte one, and two long keys that hash to the same value would be equivalent.
- Do not compare tags with ordinary string equality on a server. An early returning comparison leaks the position of the first wrong byte through timing. Use a constant time comparison function.
- TOTP codes that fail across systems are usually a shared secret encoding problem, not an algorithm problem: the secret is Base32 in the provisioning URL and raw bytes in the HMAC.
Try it: Hash Generator
Paste text or drop a file and get every digest at once, in hex or Base64, with a verify tab for comparing an expected value against what you actually have.
Hash Generator
LOCAL · Browser-OnlyGenerate MD5, SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256, SHA3-512, Keccak-256, CRC32, and HMAC hashes from text or files
MD5 is cryptographically broken and should not be used for security purposes. Use SHA-256 or SHA-512 instead.
Related Hash algorithms
All hash algorithms →HMAC-SHA-256: Signing and Verifying Payloads Correctly
HMAC-SHA-256 gives a 64 character authentication tag. Why it replaces hash(secret + body), how webhook signatures use it, and how verification goes wrong.
SHA-1: Practical Collisions and What Replaced It
SHA-1 gives a 160 bit digest, 40 hex characters. Collisions became practical in 2017 and chosen prefix collisions in 2020. What still uses it and why.
HMAC-SHA-512: 512 Bit Tags, HS512 Tokens and Key Sizing
HMAC-SHA-512 produces a 128 character tag. How HS512 tokens use it, why key length is capped by the 128 byte block, and when the width is wasted.
HMAC-SHA-384: 384 Bit Tags and the 128 Byte Block Size
HMAC-SHA-384 gives a 96 character tag over a 128 byte block. Where JWT HS384 and TLS use it, and why the key length threshold is different.
CRC32: What a Checksum Detects and What It Cannot
CRC32 gives an 8 character checksum that catches accidental corruption and nothing else. Why it is trivially forgeable and never a security control.
MD5: 128 Bit Digests, Broken Collisions, and Remaining Uses
MD5 produces a 32 character hex digest. Collisions have been practical since 2004, preimages have not. What that distinction rules out, and what it does not.
Tools for this
- Hash Generator Free online hash generator - generate MD5, SHA-1, SHA-256 hashes from any input text
- Base64 Encoder/Decoder Base64 encode and decode online - convert text to Base64 or decode Base64 strings instantly, free