HMAC (Hash-based Message Authentication Code) sử dụng hàm băm mật mã (MD5, SHA-1, SHA-256...) kết hợp khóa bí mật chung để xác thực tính toàn vẹn và nguồn gốc của dữ liệu.
Cơ chế
Hash = HMAC(key, message). Người nhận tính lại HMAC với cùng key, so sánh để xác thực.
API hmac module
import hmac, hashlib hmac_obj = hmac.new(key, msg=None, digestmod=None)
- key: Khóa bí mật (bytes)
- msg: Dữ liệu cần băm (bytes)
- digestmod: Hàm băm (mặc định MD5, khuyến nghị SHA-256)
Phương thức
| update(msg) | Cập nhật dữ liệu (có thể gọi nhiều lần) |
| digest() | Trả về bytes digest |
| hexdigest() | Trả về hex string (an toàn cho email/text) |
| copy() | Sao chép đối tượng HMAC |
Ví dụ 1: HMAC-MD5
import hmac, hashlib
data = b'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
key = b'402xy5#'
# Tạo HMAC với MD5
my_hmac = hmac.new(key, data, hashlib.md5)
print("Digest:", my_hmac.digest())
print("Hex digest:", my_hmac.hexdigest())
print("Algorithm:", my_hmac.name) # hmac-md5
print("Block size:", my_hmac.block_size) # 64 bytes
print("Digest size:", my_hmac.digest_size) # 16 bytes
# Sao chép
my_hmac_cpy = my_hmac.copy()
print("Copy digest:", my_hmac_cpy.hexdigest())
Ví dụ 2: HMAC-SHA256 (Khuyến nghị)
import hmac, hashlib
key = b'secret-key-256-bit'
message = b'Important data to authenticate'
# SHA-256 an toàn hơn MD5/SHA-1
hmac_sha256 = hmac.new(key, message, hashlib.sha256)
print("HMAC-SHA256:", hmac_sha256.hexdigest())
# Xác thực
received_hmac = hmac_sha256.hexdigest()
# Người nhận tính lại và so sánh:
# hmac.compare_digest(calculated, received) # Tránh timing attack
Ứng dụng thực tế
- API authentication (AWS, GitHub, Stripe dùng HMAC-SHA256)
- Ký request HTTP (signature trong header)
- Xác thực cookie/session
- Chữ ký số, webhook verification
- Bảo vệ dữ liệu truyền qua mạng công cộng
Best Practice
- Dùng
hmac.compare_digest()so sánh chữ ký (chống timing attack) - Khóa đủ dài (≥ 32 bytes cho SHA-256)
- Không hardcode key trong source code
- Xoay khóa định kỳ (key rotation)