MD5, SHA-1, SHA-256, SHA-512 khác nhau thế nào?
19/07/2026
Nếu bạn từng tải một file ISO và thấy trang tải kèm một chuỗi ký tự dài như d41d8cd98f00b204e9800998ecf8427e, hoặc từng nhìn thấy cột mật khẩu trong database chứa toàn ký tự hex khó hiểu, thì bạn đã gặp hàm băm (hash function). MD5, SHA-1, SHA-256, SHA-512 là những cái tên xuất hiện thường xuyên nhất — nhưng chúng khác nhau thế nào, cái nào còn an toàn, và quan trọng hơn: dùng sai chỗ nào thì hệ thống của bạn sẽ thủng? Bài viết này sẽ trả lời gọn nhưng đủ sâu.
Hàm băm là gì?
Hàm băm là một hàm nhận đầu vào có độ dài bất kỳ (một chữ, một file 4GB, cả một cơ sở dữ liệu) và cho ra một chuỗi kết quả có độ dài cố định gọi là digest (hoặc "giá trị băm"). Ví dụ SHA-256 luôn cho ra 256 bit (64 ký tự hex), bất kể đầu vào lớn cỡ nào.
Một hàm băm mật mã tốt có mấy tính chất cốt lõi:
- Một chiều (pre-image resistance): từ digest, gần như không thể tính ngược lại đầu vào ban đầu. Hash không phải mã hóa — không có "giải mã".
- Deterministic: cùng một đầu vào luôn cho ra cùng một digest, ở mọi máy, mọi thời điểm. Đây là lý do hash dùng được để so sánh và kiểm tra toàn vẹn.
- Hiệu ứng thác (avalanche effect): chỉ đổi một bit ở đầu vào, digest sẽ thay đổi hoàn toàn — khoảng một nửa số bit đầu ra lật giá trị. "hello" và "hellO" cho hai digest chẳng liên quan gì đến nhau.
- Nhanh khi tính xuôi: tính digest của một file lớn phải nhanh (điều này, nghịch lý thay, lại là vấn đề khi lưu mật khẩu — xem phần dưới).
Thế nào là một hàm băm "an toàn"?
Ngoài tính một chiều, an toàn mật mã còn đòi hỏi khó tìm va chạm (collision resistance): rất khó tìm được hai đầu vào khác nhau mà cho cùng một digest. Về lý thuyết va chạm luôn tồn tại (đầu vào vô hạn, đầu ra hữu hạn), nhưng với hàm băm tốt thì chi phí tìm ra một cặp va chạm phải lớn đến mức không khả thi trong thực tế. Khi ai đó tìm được cách tạo va chạm nhanh hơn brute-force đáng kể, thuật toán đó bị coi là "đã vỡ" (broken) và không nên dùng cho mục đích bảo mật nữa.
So sánh MD5, SHA-1, SHA-256, SHA-512
MD5 — 128 bit, đã vỡ
Ra đời năm 1992, MD5 cho digest 128 bit (32 ký tự hex). Từ 2004 người ta đã tạo được va chạm MD5, và ngày nay có thể tạo va chạm trong vài giây trên laptop thường. Đã có chứng chỉ số giả và malware ký giả mạo lợi dụng va chạm MD5. Kết luận: không bao giờ dùng MD5 cho bất cứ mục đích bảo mật nào. Nó vẫn ổn cho checksum không nhạy cảm (kiểm tra file tải về có lỗi truyền không) và làm khóa dedup, vì ở đó không có kẻ tấn công cố tình tạo va chạm.
SHA-1 — 160 bit, đã deprecated
SHA-1 cho digest 160 bit. Năm 2017 Google công bố tấn công SHAttered — tạo được hai file PDF khác nhau có cùng SHA-1. Từ đó SHA-1 bị khai tử dần: trình duyệt bỏ chứng chỉ TLS ký bằng SHA-1, và Git cũng đang chuyển dần sang SHA-256. Không dùng SHA-1 cho chữ ký hay bảo mật mới.
SHA-256 & SHA-512 — họ SHA-2, còn an toàn
SHA-256 và SHA-512 thuộc họ SHA-2 (do NSA thiết kế, NIST chuẩn hóa). Digest lần lượt 256 và 512 bit. Đến nay chưa có tấn công va chạm thực tế nào — chúng là lựa chọn mặc định cho checksum bảo mật, chữ ký số, TLS, blockchain. Điểm thú vị: trên CPU 64-bit, SHA-512 thường nhanh hơn SHA-256 vì làm việc theo word 64-bit; nếu cần bảo mật cao và chạy trên máy chủ 64-bit thì SHA-512 (hoặc SHA-512/256) là lựa chọn tốt. Còn nếu muốn hiện đại hơn nữa, xem thêm họ SHA-3 (Keccak) — thiết kế khác hẳn SHA-2.
Bạn có thể tự tính và đối chiếu digest của các thuật toán trên bằng công cụ Hash Generator ngay trên trình duyệt, dữ liệu không rời khỏi máy bạn.
| Thuật toán | Độ dài output | Tình trạng an toàn | Dùng cho |
|---|---|---|---|
| MD5 | 128 bit (32 hex) | Đã vỡ (va chạm) | Checksum không nhạy cảm, dedup — KHÔNG bảo mật |
| SHA-1 | 160 bit (40 hex) | Đã vỡ (SHAttered) | Legacy; tránh dùng cho chữ ký mới |
| SHA-256 | 256 bit (64 hex) | An toàn | Checksum bảo mật, chữ ký, TLS, blockchain |
| SHA-512 | 512 bit (128 hex) | An toàn | Như SHA-256; nhanh hơn trên CPU 64-bit |
Dùng hash đúng chỗ
- Checksum / kiểm tra toàn vẹn: tải file xong, tính hash và so với hash công bố để chắc file không bị hỏng hoặc bị chỉnh sửa. Với nguồn không có kẻ tấn công, MD5/SHA-1 vẫn đủ; với bản phát hành phần mềm quan trọng, dùng SHA-256.
- Deduplication: hệ thống lưu trữ dùng hash của nội dung làm khóa để phát hiện các file trùng nhau mà không cần so từng byte.
- ETag / cache: web server sinh ETag từ hash nội dung; trình duyệt gửi lại để hỏi "nội dung có đổi không", tiết kiệm băng thông.
- Chữ ký số & Git: ký digest (SHA-256) thay vì ký cả file; Git định danh mỗi commit/blob bằng hash nội dung.
CẢNH BÁO: đừng dùng MD5/SHA-256 trơn để lưu mật khẩu
Đây là lỗi bảo mật kinh điển. Tuyệt đối không lưu mật khẩu bằng md5(password) hay sha256(password) trơn. Lý do:
- Hash quá nhanh: chính ưu điểm "tính nhanh" trở thành điểm yếu. GPU hiện đại thử hàng tỷ SHA-256 mỗi giây, nên brute-force mọi mật khẩu ngắn/yếu là chuyện trong tầm tay khi database bị lộ.
- Không có salt: hai người dùng đặt cùng mật khẩu sẽ có cùng digest. Kẻ tấn công dùng rainbow table (bảng digest tính sẵn) tra ngược tức thì, hoặc bẻ nhiều tài khoản cùng lúc.
Giải pháp đúng là các hàm băm mật khẩu chuyên dụng: Argon2 (khuyến nghị hàng đầu hiện nay), scrypt, bcrypt, hoặc PBKDF2. Chúng được thiết kế để chậm có chủ đích (work factor điều chỉnh được) và tự thêm salt cho từng mật khẩu, khiến brute-force và rainbow table trở nên bất khả thi về chi phí. Argon2 và scrypt còn tốn nhiều bộ nhớ (memory-hard) để làm khó cả tấn công bằng GPU/ASIC.
Ví dụ thực tế
Chuỗi "hello" qua vài thuật toán cho các digest sau (bạn có thể tự kiểm chứng):
- MD5:
5d41402abc4b2a76b9719d911017c592 - SHA-1:
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d - SHA-256:
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Chú ý độ dài digest tăng dần theo thuật toán, và đúng như tính deterministic, "hello" luôn cho ra chính những chuỗi này ở mọi ngôn ngữ, mọi hệ điều hành.
Tính SHA-256 trong trình duyệt bằng Web Crypto API (chuẩn, không cần thư viện):
async function sha256(text) {
const data = new TextEncoder().encode(text);
const buf = await crypto.subtle.digest("SHA-256", data);
return [...new Uint8Array(buf)]
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
sha256("hello").then((h) => console.log(h));
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Trên Node.js dùng module crypto có sẵn:
const { createHash } = require("crypto");
const digest = createHash("sha256").update("hello").digest("hex");
console.log(digest);
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Tóm lại
Hash là công cụ một chiều, deterministic, có hiệu ứng thác — tuyệt vời để kiểm tra toàn vẹn và định danh nội dung. MD5 và SHA-1 đã vỡ, chỉ còn dùng được cho checksum không nhạy cảm; SHA-256 và SHA-512 vẫn an toàn và là lựa chọn mặc định cho bảo mật. Và hãy khắc cốt ghi tâm: mật khẩu không bao giờ được băm bằng hash mật mã trơn — luôn dùng Argon2/scrypt/bcrypt/PBKDF2 với salt và work factor.
Muốn tính nhanh MD5, SHA-1, SHA-256, SHA-512 cho một chuỗi hay so sánh checksum ngay trên trình duyệt mà không gửi dữ liệu đi đâu? Dùng ngay Hash Generator của DevToolHub.