HMAC Generator
Generate HMAC signatures with SHA-256, SHA-384, or SHA-512
Message
Secret Key
HMAC Signature
HMAC signature will appear here…
What Is HMAC?
HMAC (Hash-based Message Authentication Code) is a cryptographic construction defined in RFC 2104 that combines a hash function with a secret key to produce a fixed-size authentication tag. Unlike a plain hash, which anyone can compute, an HMAC can only be generated and verified by parties who share the secret key. HMAC is the standard mechanism for verifying both the integrity and authenticity of a message — confirming that the data has not been altered and that it was produced by a trusted sender.
The HMAC algorithm works with any iterative hash function: SHA-256, SHA-384, SHA-512, and even legacy functions like SHA-1 or MD5. The resulting construct is referred to by its underlying hash — HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. Because HMAC's security proof depends on the hash function being collision-resistant and having certain pseudorandom properties, SHA-2 family algorithms are the recommended choice for new systems. HMAC-SHA256 is the most widely deployed variant, used in AWS Signature V4, Stripe webhooks, GitHub webhook secrets, Slack request signing, and JSON Web Tokens (HS256).
HMAC's design provides a critical property that plain hashing lacks: resistance to length-extension attacks. With SHA-256 alone, an attacker who knows H(message) can compute H(message || attacker_data) without knowing the original message. HMAC's double-hashing structure (inner hash and outer hash with different padded keys) prevents this attack entirely. This is why API signature schemes use HMAC rather than appending a secret key to the message and hashing the result.
Why Use an Online HMAC Generator?
Computing HMAC signatures typically requires writing code or using CLI tools. This browser-based HMAC generator lets you create HMAC-SHA256, HMAC-SHA384, and HMAC-SHA512 signatures instantly without installing software or switching to a terminal.
HMAC Generator Use Cases
HMAC vs Plain Hash vs Encryption
HMAC, plain hashing, and encryption serve different purposes. HMAC provides message authentication — proof that the message was created by someone with the secret key and has not been modified. A plain hash provides integrity but not authentication. Encryption provides confidentiality. The table below clarifies the distinctions.
| Property | HMAC | Plain Hash | Encryption |
|---|---|---|---|
| Purpose | Message authentication + integrity | Data integrity only (no key) | Confidentiality + integrity |
| Requires secret key | Yes | No | Yes |
| Verifiable by | Parties who share the secret | Anyone | Recipient with key |
| Reversible | No — digest only | No — digest only | Yes — decryption recovers data |
| Output size | Depends on hash (e.g. 256 bits) | Depends on hash | Variable (ciphertext) |
| Standard | RFC 2104 | FIPS 180-4 | NIST SP 800-38A (AES) |
| Use case example | Webhook signature verification | File checksum verification | Encrypting data at rest |
HMAC Algorithm Comparison
HMAC can use any hash function, but the choice of underlying algorithm determines the output size, security level, and browser compatibility. HMAC-SHA256 is the most common choice for new systems. The table below compares the variants you are likely to encounter.
| Algorithm | Digest Size | Hex Length | Web Crypto | Best For |
|---|---|---|---|---|
| HMAC-SHA256 | 256 bits | 64 hex chars | Yes | API signing, webhooks, JWT (HS256) |
| HMAC-SHA384 | 384 bits | 96 hex chars | Yes | TLS 1.3 PRF, CNSA compliance |
| HMAC-SHA512 | 512 bits | 128 hex chars | Yes | High-security signatures, HKDF |
| HMAC-SHA1 | 160 bits | 40 hex chars | Yes | Legacy OAuth 1.0, TOTP (RFC 6238) |
| HMAC-MD5 | 128 bits | 32 hex chars | No | Legacy only — not recommended |
How HMAC Works Internally
HMAC applies the underlying hash function twice with two different key-derived pads. The construction is defined in RFC 2104 and proven to be a PRF (pseudorandom function) under standard cryptographic assumptions. The key is first padded or hashed to match the hash function's block size (64 bytes for SHA-256, 128 bytes for SHA-512).
where K' = key padded to block size, ipad = 0x36, opad = 0x5C
The algorithm XORs the padded key with an inner pad constant (ipad, 0x36 repeated), concatenates it with the message, and hashes the result. It then XORs the padded key with an outer pad constant (opad, 0x5C repeated), concatenates it with the inner hash output, and hashes again. This double-hashing structure is what prevents length-extension attacks and ensures that the HMAC output cannot be computed without knowledge of the secret key.
HMAC Code Examples
HMAC is supported natively in every major language and runtime. The Web Crypto API provides HMAC-SHA256, HMAC-SHA384, and HMAC-SHA512 in browsers without any library. The examples below show real-world usage patterns including webhook verification and constant-time comparison.
async function hmacSHA256(message, secret) {
const enc = new TextEncoder()
const key = await crypto.subtle.importKey(
'raw', enc.encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false, ['sign']
)
const sig = await crypto.subtle.sign('HMAC', key, enc.encode(message))
return Array.from(new Uint8Array(sig))
.map(b => b.toString(16).padStart(2, '0')).join('')
}
await hmacSHA256('hello world', 'my-secret-key')
// → "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"
// Node.js (built-in crypto module)
const crypto = require('crypto')
crypto.createHmac('sha256', 'my-secret-key')
.update('hello world').digest('hex')
// → "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"import hmac
import hashlib
# HMAC-SHA256
sig = hmac.new(
b'my-secret-key',
b'hello world',
hashlib.sha256
).hexdigest()
print(sig)
# → "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"
# Verify a webhook signature (constant-time comparison)
expected = "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"
received = hmac.new(b'my-secret-key', b'hello world', hashlib.sha256).hexdigest()
if hmac.compare_digest(expected, received):
print("Signature valid")
# HMAC-SHA512
hmac.new(b'key', b'data', hashlib.sha512).hexdigest()package main
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
)
func main() {
mac := hmac.New(sha256.New, []byte("my-secret-key"))
mac.Write([]byte("hello world"))
sig := mac.Sum(nil)
fmt.Printf("%x\n", sig)
// → 90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad
// Verify: use hmac.Equal for constant-time comparison
expected := mac.Sum(nil)
fmt.Println(hmac.Equal(sig, expected)) // true
}# HMAC-SHA256 echo -n "hello world" | openssl dgst -sha256 -hmac "my-secret-key" # → SHA2-256(stdin)= 90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad # HMAC-SHA512 echo -n "hello world" | openssl dgst -sha512 -hmac "my-secret-key" # Verify a file signature openssl dgst -sha256 -hmac "my-secret-key" release.tar.gz # HMAC with hex key (e.g. from a webhook secret) echo -n "payload" | openssl dgst -sha256 -hmac "$(echo -n '736563726574' | xxd -r -p)"