🔴 Encryption (Mã hóa)
2 chiều: Có thể mã hóa VÀ giải mã. Cần key để encrypt/decrypt. Dùng để bảo vệ data truyền tải.
🟣 Hashing (Băm)
1 chiều: Chỉ băm, KHÔNG thể giải ngược. Cùng input → cùng output. Dùng để verify data integrity.
1. Encryption — Mã Hóa
Encryption (2 chiều):
"Hello" + Key → encrypt → "x7Kp9..." → decrypt + Key → "Hello"
Symmetric (cùng key): AES, ChaCha20
encrypt(data, key) → ciphertext
decrypt(ciphertext, key) → data
Asymmetric (2 keys): RSA, ECC
encrypt(data, publicKey) → ciphertext
decrypt(ciphertext, privateKey) → data
const crypto = require('crypto');
// === AES-256 Symmetric Encryption ===
const algorithm = 'aes-256-gcm';
const key = crypto.randomBytes(32); // 256-bit key
function encrypt(text) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag();
return { iv: iv.toString('hex'), encrypted, authTag: authTag.toString('hex') };
}
function decrypt({ iv, encrypted, authTag }) {
const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(iv, 'hex'));
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const result = encrypt('Số thẻ: 4111-1111-1111-1111');
console.log('Encrypted:', result.encrypted);
console.log('Decrypted:', decrypt(result)); // → "Số thẻ: 4111-1111-1111-1111"
2. Hashing — Băm
Hashing (1 chiều):
"Hello" → hash → "185f8db3..." (KHÔNG thể giải ngược)
"Hello" → hash → "185f8db3..." (cùng input = cùng output)
"Hello!" → hash → "a8cfcd74..." (khác 1 ký tự = đổi hoàn toàn)
const crypto = require('crypto');
const bcrypt = require('bcrypt');
// === SHA-256 (Fast hash - cho file integrity) ===
const hash = crypto.createHash('sha256')
.update('Hello World')
.digest('hex');
console.log(hash); // "a591a6d4..." (luôn 64 ký tự)
// === bcrypt (Slow hash - cho passwords) ===
// Tại sao slow? Để chống brute-force!
async function hashPassword(password) {
const saltRounds = 12; // chi phí tính toán cao
return await bcrypt.hash(password, saltRounds);
}
async function verifyPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
// Sử dụng:
const hashed = await hashPassword('myPassword123');
// "$2b$12$LJ3m4ys..." (chứa salt + hash)
const isValid = await verifyPassword('myPassword123', hashed);
// true ✅ (KHÔNG cần giải mã, chỉ so sánh)
3. Bảng So Sánh
| Tiêu chí | 🔴 Encryption | 🟣 Hashing |
|---|---|---|
| Chiều | 2 chiều (encrypt ↔ decrypt) | 1 chiều (hash → không giải được) |
| Cần key? | Có (symmetric hoặc asymmetric) | Không (chỉ cần thuật toán) |
| Output size | Phụ thuộc input size | Cố định (SHA-256 = 256 bit) |
| Mục đích | Bảo vệ data confidentiality | Verify integrity, lưu passwords |
| Use cases | HTTPS, VPN, file encryption | Password storage, checksums, digital signatures |
| Thuật toán | AES, RSA, ChaCha20 | SHA-256, bcrypt, Argon2 |
4. Khi Nào Dùng?
Dùng Encryption khi:
• Cần đọc lại data gốc (credit card, messages, files)
• Truyền data qua mạng (HTTPS/TLS)
• Lưu trữ data nhạy cảm cần truy xuất
Dùng Hashing khi:
• Lưu passwords (bcrypt, Argon2)
• Verify file integrity (checksums SHA-256)
• Digital signatures
• Data deduplication
⚠️ Sai lầm phổ biến:
• ❌ Dùng MD5/SHA1 cho passwords (quá nhanh, dễ brute-force)
• ❌ Encrypt passwords (nếu key bị lộ → tất cả passwords lộ)
• ❌ Dùng hashing cho data cần đọc lại
• ✅ Luôn dùng bcrypt/Argon2 cho passwords