🔒 Encryption vs Hashing

Mã hóa 2 chiều (có thể giải) vs Băm 1 chiều (không thể giải)

🔴 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