Công Cụ Này Là Gì?
HMAC là viết tắt của Hash-based Message Authentication Code. Nó kết hợp một khóa bí mật với một thông điệp và một hàm hash tiêu chuẩn (như SHA-256) để tạo ra một digest có độ dài cố định. Bất kỳ ai có cùng khóa và cùng thông điệp đều sẽ tính ra chính xác cùng một mã HMAC — nhưng nếu không có khóa, việc tạo ra một mã HMAC hợp lệ cho một thông điệp là bất khả thi về mặt tính toán, ngay cả khi biết rõ thuật toán hash đang dùng.
Đây chính là khác biệt cốt lõi so với hash thông thường: một hash thông thường (MD5, SHA-256, v.v.) chỉ nhận thông điệp làm đầu vào, nên ai cũng tính được và nó không chứng minh được gì về người tạo ra nó. HMAC nhận cả thông điệp *và* một khóa bí mật, nên một mã HMAC hợp lệ chứng minh người gửi thực sự sở hữu khóa bí mật đó — đây là cơ chế xác thực, chứ không đơn thuần chỉ là kiểm tra tính toàn vẹn.
HMAC được NIST chuẩn hóa chính thức trong FIPS 198-1 và được định nghĩa cho các giao thức Internet trong IETF RFC 2104. Công cụ này tính HMAC bằng Web Crypto API gốc của trình duyệt (`crypto.subtle.sign` với thuật toán HMAC), triển khai đúng theo RFC 2104 thay vì một phiên bản JavaScript tự viết tay.
Tại Sao Nên Dùng?
- Endpoint webhook Stripe của bạn vừa từ chối một request vì lỗi signature mismatch, và bạn cần tự tính lại HMAC-SHA256 từ payload và secret để tìm ra chỗ sai lệch.
- Bạn đang viết tài liệu tích hợp API nội bộ và cần một ví dụ HMAC chính xác để trình bày cho đội bên ngoài, mà không muốn chạy cả script backend chỉ để lấy một ví dụ.
- Đoạn code HMAC Node.js hoặc Python bạn vừa viết cho ra kết quả khác với mong đợi, và bạn cần một giá trị tham chiếu độc lập từ một triển khai khác để tìm ra lỗi.
- Bạn đang debug tích hợp webhook GitHub và cần xác minh header X-Hub-Signature-256 nhận được có khớp với HMAC tính từ payload thô và secret webhook không.
- Bạn cần tính ngay HMAC cho secret production thật trong lúc xử lý sự cố, và không muốn gửi secret đó lên bất kỳ máy chủ bên thứ ba nào.
- 100% cục bộ: khóa bí mật và thông điệp của bạn không bao giờ rời khỏi trình duyệt, nên hoàn toàn an toàn để thử nghiệm với khóa bí mật thật.
Cách Sử Dụng
- Nhập khóa bí mật của bạn vào trường "Secret Key".
- Nhập thông điệp bạn muốn xác thực vào trường "Message".
- Kết quả HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 và HMAC-SHA512 được tạo ngay lập tức (đánh dấu "Uppercase output" nếu hệ thống đích của bạn yêu cầu chữ in hoa).
- Nhấn "Copy" bên cạnh mã HMAC bạn cần.
Ví dụ
Đầu vào
Secret Key: key
Message: The quick brown fox jumps over the lazy dogĐầu ra
HMAC-SHA256: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
HMAC-SHA1: de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9Đây là một test vector tiêu chuẩn đã được công bố: với khóa "key" và chính xác thông điệp này, HMAC-SHA256 và HMAC-SHA1 luôn cho ra các giá trị này trên bất kỳ triển khai đúng nào, nên bạn có thể tự kiểm chứng kết quả của công cụ này một cách độc lập.
HMAC và hash thông thường: khi nào cần khóa
Câu hỏi quyết định là: bạn cần chứng minh ai đã tạo ra digest này, hay chỉ cần chứng minh nội dung không bị thay đổi? Nếu một checksum công khai là đủ — xác minh file tải về khớp với công bố của nhà phát hành, loại bỏ bản ghi trùng lặp — thì hash thông thường đáp ứng được và ai cũng kiểm tra được, không cần khóa. Nếu bạn cần chứng minh digest chỉ có thể được tạo ra bởi người nắm giữ một khóa bí mật cụ thể — xác thực bên gọi API, tin tưởng người gửi webhook — bạn cần HMAC, vì hash thông thường cho kẻ tấn công không có khóa bí mật khả năng giả mạo digest hợp lệ y hệt người gửi thật.
→ Công Cụ Tạo Hash Đa Thuật Toán · Công Cụ Giải Mã JWT · Công Cụ Tạo MD5
So sánh bốn thuật toán HMAC
Cả bốn đều dùng chung cấu trúc HMAC theo RFC 2104, chỉ khác nhau ở hàm hash nền, do đó khác nhau về độ dài output.
| Thuật toán | Kích thước output | Ứng dụng thường gặp |
|---|---|---|
| HMAC-SHA1 | 160-bit (40 ký tự hex) | API đời cũ, chữ ký OAuth 1.0a đời trước |
| HMAC-SHA256 | 256-bit (64 ký tự hex) | Ký request API, JWT HS256, xác minh webhook |
| HMAC-SHA384 | 384-bit (96 ký tự hex) | Chữ ký yêu cầu độ tin cậy cao hơn, cần output dài hơn |
| HMAC-SHA512 | 512-bit (128 ký tự hex) | Digest độ dài tối đa cho các ứng dụng bảo mật cao |
Các trường hợp sử dụng phổ biến
- Ký các request API gửi đi bằng một khóa bí mật dùng chung để server xác minh danh tính bên gọi.
- Xác minh payload webhook đến (các header như Stripe-Signature, GitHub X-Hub-Signature-256 và tương tự đều dùng HMAC-SHA256).
- Tạo và xác thực phần chữ ký của JWT được ký bằng HS256/HS384/HS512.
- Kiểm tra xem triển khai HMAC phía server hoặc phía client của bạn có khớp với output kỳ vọng trước khi triển khai thực tế hay không.
Những lỗi thường gặp khi tự triển khai HMAC
Hầu hết các lỗi "HMAC của tôi không khớp" không đến từ việc chọn sai thuật toán, mà từ những chi tiết nhỏ trong cách khóa và thông điệp được chuẩn bị trước khi tính toán.
- Đảm bảo khóa được xử lý với cùng một encoding ở cả hai phía — một chuỗi UTF-8 thông thường và một chuỗi hex/base64 đã được decode sẽ cho ra HMAC hoàn toàn khác nhau dù trông có vẻ giống nhau.
- Với việc xác minh webhook, luôn tính HMAC từ payload thô (raw body) trước khi nó được parse thành đối tượng JSON — nhiều framework backend tự động parse body request, và nếu bạn tính lại từ đối tượng đã được stringify lại, thứ tự key hay khoảng trắng có thể khác với body gốc mà bên gửi đã gửi đi.
- Luôn dùng phép so sánh constant-time (không phải `===` thông thường) khi xác minh HMAC trong code production của bạn, để tránh lỗ hổng timing attack — công cụ này chỉ dùng để tạo và so sánh trực quan lúc debug, không thay thế logic xác minh trong production.
Câu Hỏi Thường Gặp
HMAC là gì?
HMAC (Hash-based Message Authentication Code) kết hợp một khóa bí mật với một thông điệp bằng một hàm hash để tạo ra một digest chứng minh cả tính toàn vẹn của thông điệp lẫn việc người gửi sở hữu khóa đó. Nó được định nghĩa trong NIST FIPS 198-1 và IETF RFC 2104.
Sự khác biệt giữa HMAC và hash thông thường là gì?
Một hash thông thường (SHA-256, MD5, v.v.) chỉ nhận thông điệp làm đầu vào — ai cũng tính được, nên nó chỉ chứng minh thông điệp không bị hỏng chứ không chứng minh được ai đã gửi nó. HMAC nhận thông điệp cộng thêm một khóa bí mật: nếu bạn cần chứng minh một thông điệp đến từ người nắm giữ một khóa bí mật cụ thể (chữ ký API, người gửi webhook), bạn cần HMAC. Nếu chỉ cần kiểm tra một file hay thông điệp không bị thay đổi mà không quan tâm đến việc chứng minh ai là tác giả, hash thông thường là đủ.
Khóa bí mật của tôi có được gửi lên máy chủ không?
Không. Công cụ này tính HMAC hoàn toàn trong trình duyệt của bạn bằng Web Crypto API. Khóa và thông điệp của bạn không bao giờ được truyền đi đâu cả — bạn có thể yên tâm thử nghiệm với các khóa bí mật thật trong môi trường production.
Nên dùng thuật toán nào — SHA-1, SHA-256, SHA-384 hay SHA-512?
Hãy dùng HMAC-SHA256 trừ khi hệ thống cụ thể yêu cầu khác — đây là tiêu chuẩn thực tế cho việc ký API (được AWS, Stripe, webhook của GitHub và hầu hết các API hiện đại sử dụng) và mang lại mức độ an toàn cao. HMAC-SHA1 vẫn còn phổ biến trong các hệ thống cũ (như các triển khai OAuth 1.0a đời trước) nhưng hash nền của SHA-1 bị xem là yếu hơn; HMAC-SHA384/512 được dùng khi cần độ dài output lớn hơn hoặc mức an toàn cao hơn hẳn.
HMAC-SHA1 có không an toàn không, vì SHA-1 thuần đã bị phá vỡ?
Các cuộc tấn công va chạm (collision) năm 2017 nhắm vào SHA-1 đã phá vỡ SHA-1 như một hàm hash thông thường, nhưng HMAC-SHA1 vẫn được xem là an toàn về mặt mật mã học vì độ an toàn của HMAC không phụ thuộc vào khả năng chống va chạm theo cách tương tự. Dù vậy, hãy ưu tiên HMAC-SHA256 trở lên cho các hệ thống mới — không có nhược điểm thực tế nào và tránh được hoàn toàn vấn đề này.
Các ứng dụng thực tế phổ biến của HMAC là gì?
Ký các request REST API để server có thể xác minh bên gọi nắm giữ khóa API dùng chung; xác minh payload webhook từ các dịch vụ như Stripe, GitHub và Shopify để biết chắc request thực sự đến từ họ và không bị giả mạo; tạo mật khẩu dùng một lần theo thời gian (TOTP/HOTP) cho xác thực hai yếu tố; và ký token JWT bằng các thuật toán HS256/HS384/HS512.
Tại sao HMAC tôi tự tính trong code lại khác với kết quả của công cụ này?
Nguyên nhân phổ biến nhất là encoding của thông điệp hoặc khóa không nhất quán (ví dụ khóa được xử lý như UTF-8 ở một phía nhưng là hex ở phía kia), khoảng trắng hoặc ký tự xuống dòng ẩn lọt vào payload (thường xảy ra khi bạn copy-paste từ JSON đã được format lại), hoặc dùng nhầm khóa của môi trường khác (secret staging dùng để xác minh payload production). Hãy kiểm tra biểu diễn byte chính xác của khóa và thông điệp trước khi đổ lỗi cho thuật toán.
Thứ tự khóa và thông điệp có quan trọng không — có thể đảo ngược không?
Không thể đảo ngược tùy tiện. HMAC được định nghĩa cụ thể là H(key XOR opad, H(key XOR ipad, message)) theo RFC 2104 — khóa và thông điệp có vai trò toán học khác nhau trong cấu trúc này, không đơn thuần là hai đầu vào có thể hoán đổi vị trí. Đảo ngược cái nào là "khóa" và cái nào là "thông điệp" sẽ cho ra một HMAC hoàn toàn khác.
HMAC có thể dùng để mã hóa dữ liệu thay vì chỉ xác minh không?
Không — HMAC là một hàm một chiều tạo ra digest cố định, không phải cơ chế mã hóa. Bạn không thể "giải mã" HMAC để lấy lại thông điệp gốc; HMAC chỉ chứng minh tính toàn vẹn và xác thực của một thông điệp bạn đã biết, chứ không che giấu nội dung của nó. Để mã hóa, bạn cần một thuật toán riêng như AES.
Điều gì xảy ra nếu khóa bí mật của tôi ngắn hơn kích thước block của hàm hash?
Theo RFC 2104, nếu khóa ngắn hơn kích thước block nội bộ của hàm hash (64 byte cho SHA-1/SHA-256, 128 byte cho SHA-384/SHA-512), khóa đó sẽ được đệm thêm byte 0 ở cuối cho đến khi đạt kích thước block trước khi dùng trong phép tính — việc này được Web Crypto API xử lý tự động, bạn không cần tự đệm thủ công.