Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình

Password Salting (Muối mật khẩu) trong An ninh Thông tin

Password Salting là kỹ thuật thêm giá trị ngẫu nhiên duy nhất (salt) vào mật khẩu trước khi băm: Hash = H(salt || password). Mục đích: chống precomputation attack (rainbow table, lookup table) và đảm bảo cùng mật khẩu → hash khác nhau.

Tại sao cần Salt?

  • Không salt: Cùng password → cùng hash. Kẻ có DB hash → tra rainbow table / precomputed hash dictionary → crack hàng loạt.
  • Có salt duy nhất/user: Cùng password → hash khác nhau. Kẻ phải tấn công từng user riêng lẻ (tăng chi phí tuyến tính với số user).
  • Chống credential stuffing: Hash bị rò rỉ từ site A không dùng được cho site B (salt khác).

Yêu cầu kỹ thuật cho Salt

  1. Duy nhất (Unique): Mỗi password có salt riêng. Không reuse salt.
  2. Ngẫu nhiên mật mã (Cryptographically Random): Sinh từ CSPRNG (OS: /dev/urandom, getrandom(), BCryptGenRandom, libsodium randombytes). Độ dài ≥ 128-bit (16 byte), khuyến nghị 256-bit (32 byte).
  3. Lưu trữ công khai: Salt không cần bí mật — lưu cùng hash trong DB: $algorithm$cost$salt$hash (modular crypt format).
  4. Không phải secret: Salt ≠ Pepper. Pepper = secret key thêm vào (HMAC/encryption) — lưu riêng (HSM/env var), không trong DB.

Triển khai chuẩn (Modular Crypt Format - MCF)

$argon2id$v=19$m=65536,t=3,p=4$c2FsdHR2YWx1ZQ$hash_base64
$bcrypt$12$saltvalue$hashvalue
$scrypt$N=16384,r=8,p=1$salt$hash
$pbkdf2_sha256$260000$salt$hash
  • Format: $id$params$salt$hash — tự chứa thuật toán, tham số, salt, hash.
  • Dễ upgrade:.verify() đọc params từ hash stored, rehash nếu params cũ (upgrade on login).

Salt vs Pepper

Thuộc tínhSaltPepper
Bí mậtKhông (public, lưu DB)Có (secret, lưu HSM/env/KMS)
Duy nhất/userCóThường chung toàn hệ thống (hoặc rotate)
Mục đíchChống precomputation, unique hashChống offline attack nếu DB leak (cần cả pepper)
RotateKhông cần (per-user unique)Có thể rotate (re-encrypt hash)

Best Practice: Dùng Salt (bắt buộc) + Pepper (defense-in-depth, nếu HSM/KMS khả dụng).

Thuật toán Password Hashing khuyên dùng (2024)

  1. Argon2id (PHC Winner 2015): Memory-hard (m KB), Time-hard (t passes), Parallelism (p lanes). Mặc định: m=64MB, t=3, p=4. Chống GPU/ASIC/FPGA tốt nhất.
  2. bcrypt: Blowfish-based, cost factor (log₂ rounds). Giới hạn 72 byte input. Phổ biến, hỗ trợ rộng. Cost ≥ 12 (2024).
  3. scrypt: N, r, p params. Memory-hard gốc. Dùng Litecoin. Ít support hơn Argon2.
  4. PBKDF2-HMAC-SHA256: Chỉ time-hard (iteration count). Chỉ dùng khi bắt buộc FIPS/legacy. Iterations ≥ 600,000 (2024).

Sai lầm thường gặp

  • Dùng salt cố định / hardcode / timestamp / username làm salt.
  • Dùng hash nhanh (SHA-256, MD5) + salt → vẫn bị GPU brute-force nhanh.
  • Không lưu salt / lưu riêng hash → không verify được.
  • Salt quá ngắn (< 64-bit) → collision salt khả thi.
  • Không upgrade hash params khi user login (rehash với params mới).

Code mẫu (Python - passlib / argon2-cffi)

from passlib.hash import argon2

# Hash (register / change password)
hash = argon2.hash(password)  # auto gen salt, default params
# Verify (login)
if argon2.verify(password, stored_hash):
    # Optional: upgrade if params outdated
    if argon2.needs_update(stored_hash):
        new_hash = argon2.hash(password)
        db.update(user_id, new_hash)

Tóm lại: Salt = giá trị ngẫu nhiên duy nhất per-password, lưu công khai, bắt buộc cho mọi password hashing. Kết hợp với KDF chậm (Argon2id/bcrypt) + optional Pepper = bảo vệ mật khẩu tiêu chuẩn vàng 2024.