Trình tạo HMAC
Tạo chữ ký HMAC với SHA-256, SHA-384 hoặc SHA-512
Tin nhắn
Khoá bí mật
Chữ ký HMAC
Chữ ký HMAC sẽ xuất hiện ở đây…
HMAC là gì?
HMAC (Hash-based Message Authentication Code — Mã xác thực thông điệp dựa trên băm) là cấu trúc mật mã được định nghĩa trong RFC 2104, kết hợp hàm băm với khoá bí mật để tạo ra thẻ xác thực có kích thước cố định. Không giống như một giá trị băm thông thường mà bất kỳ ai cũng có thể tính toán, HMAC chỉ có thể được tạo ra và xác minh bởi các bên chia sẻ khoá bí mật. HMAC là cơ chế tiêu chuẩn để xác minh cả tính toàn vẹn và tính xác thực của thông điệp — xác nhận rằng dữ liệu chưa bị sửa đổi và được tạo ra bởi người gửi đáng tin cậy.
Thuật toán HMAC hoạt động với bất kỳ hàm băm lặp nào: SHA-256, SHA-384, SHA-512, và thậm chí các hàm cũ như SHA-1 hoặc MD5. Cấu trúc kết quả được gọi theo hàm băm cơ sở — HMAC-SHA256, HMAC-SHA384 hoặc HMAC-SHA512. Vì bằng chứng bảo mật của HMAC dựa vào hàm băm có khả năng kháng va chạm và các tính chất giả ngẫu nhiên nhất định, các thuật toán họ SHA-2 là lựa chọn được khuyến nghị cho các hệ thống mới. HMAC-SHA256 là biến thể được triển khai rộng rãi nhất, được dùng trong AWS Signature V4, Stripe webhooks, GitHub webhook secrets, Slack request signing và JSON Web Tokens (HS256).
Thiết kế của HMAC cung cấp một tính chất quan trọng mà băm thông thường thiếu: khả năng kháng các cuộc tấn công mở rộng độ dài. Với SHA-256 đơn thuần, kẻ tấn công biết H(message) có thể tính H(message || attacker_data) mà không cần biết thông điệp gốc. Cấu trúc băm kép của HMAC (băm bên trong và băm bên ngoài với các khoá đệm khác nhau) ngăn chặn hoàn toàn cuộc tấn công này. Đây là lý do tại sao các sơ đồ ký API sử dụng HMAC thay vì nối khoá bí mật vào thông điệp rồi băm kết quả.
Tại sao dùng trình tạo HMAC trực tuyến?
Thông thường, tính toán chữ ký HMAC đòi hỏi phải viết code hoặc dùng công cụ CLI. Trình tạo HMAC trên trình duyệt này cho phép bạn tạo chữ ký HMAC-SHA256, HMAC-SHA384 và HMAC-SHA512 ngay lập tức mà không cần cài đặt phần mềm hay chuyển sang terminal.
Các trường hợp sử dụng trình tạo HMAC
HMAC so với băm thông thường và mã hóa
HMAC, băm thông thường và mã hóa phục vụ các mục đích khác nhau. HMAC cung cấp xác thực thông điệp — bằng chứng rằng thông điệp được tạo ra bởi người nắm khoá bí mật và chưa bị sửa đổi. Băm thông thường cung cấp tính toàn vẹn nhưng không xác thực. Mã hóa cung cấp tính bảo mật. Bảng dưới đây làm rõ sự khác biệt.
| Thuộc tính | 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 |
So sánh các thuật toán HMAC
HMAC có thể dùng bất kỳ hàm băm nào, nhưng lựa chọn thuật toán cơ sở quyết định kích thước đầu ra, mức độ bảo mật và khả năng tương thích trình duyệt. HMAC-SHA256 là lựa chọn phổ biến nhất cho các hệ thống mới. Bảng dưới đây so sánh các biến thể bạn có khả năng gặp.
| Thuật toán | Kích thước Digest | Độ dài Hex | Web Crypto API | Phù hợp nhất cho |
|---|---|---|---|---|
| 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 |
HMAC hoạt động bên trong như thế nào?
HMAC áp dụng hàm băm cơ sở hai lần với hai pad dẫn xuất từ khoá khác nhau. Cấu trúc được định nghĩa trong RFC 2104 và được chứng minh là PRF (hàm giả ngẫu nhiên) dưới các giả định mật mã tiêu chuẩn. Khoá trước tiên được đệm hoặc băm để khớp với kích thước khối của hàm băm (64 byte với SHA-256, 128 byte với SHA-512).
where K' = key padded to block size, ipad = 0x36, opad = 0x5C
Thuật toán XOR khoá đã đệm với hằng số pad bên trong (ipad, 0x36 lặp lại), nối với thông điệp và băm kết quả. Sau đó XOR khoá đã đệm với hằng số pad bên ngoài (opad, 0x5C lặp lại), nối với đầu ra băm bên trong và băm lần nữa. Cấu trúc băm kép này là thứ ngăn chặn các cuộc tấn công mở rộng độ dài và đảm bảo rằng đầu ra HMAC không thể tính được nếu không biết khoá bí mật.
Ví dụ code HMAC
HMAC được hỗ trợ nguyên bản trong mọi ngôn ngữ và môi trường thực thi lớn. Web Crypto API cung cấp HMAC-SHA256, HMAC-SHA384 và HMAC-SHA512 trong trình duyệt mà không cần thư viện nào. Các ví dụ dưới đây minh họa các mẫu sử dụng thực tế bao gồm xác minh webhook và so sánh theo thời gian hằng định.
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)"