bcrypt được thiết kế đặc biệt cho password hashing — khác hoàn toàn SHA-256/MD5 vốn được tối ưu để NHANH (SHA-256 hash 10 tỷ lần/giây trên GPU, bcrypt cost=12 chỉ ~250 lần/giây).
- Adaptive cost factor:
saltRounds(cost) tăng thì thời gian tăng gấp đôi — cost=10 ~100ms, cost=12 ~400ms, cost=14 ~1.6s. - Chọn cost sao cho ~250ms trên server của bạn và tăng dần theo năm khi phần cứng mạnh lên.
- Built-in salt: bcrypt tự tạo random salt unique per password và nhúng vào hash output — tránh rainbow table attacks và đảm bảo cùng password tạo hash khác nhau mỗi lần.
- Timing attacks:
bcrypt.compare()là constant-time comparison, không dùng===để so sánh hash. - Argon2 là alternative hiện đại hơn (winner PHC 2015): argon2id kháng GPU và side-channel attacks tốt hơn, được OWASP khuyến nghị năm 2023+; dùng
argon2package trong Node.js. - Lưu ý: hash password trong service layer, không trong model hook — dễ bị double-hash nếu hook chạy lại khi update field khác.
bcrypt was specifically designed for password hashing — completely unlike SHA-256/MD5 which are optimized to be FAST (SHA-256 can hash 10 billion times per second on a GPU; bcrypt with cost=12 only ~250 times per second).
- Adaptive cost factor: increasing
saltRounds(cost) doubles the time — cost=10 ~100ms, cost=12 ~400ms, cost=14 ~1.6s. - Choose cost so each hash takes ~250ms on your server and increase it over time as hardware improves.
- Built-in salt: bcrypt automatically generates a unique random salt per password and embeds it in the hash output — prevents rainbow table attacks and ensures the same password produces a different hash each time.
- Timing attacks:
bcrypt.compare()is a constant-time comparison; never use===to compare hashes. - Argon2 is a more modern alternative (PHC winner 2015): argon2id resists GPU and side-channel attacks better, recommended by OWASP since 2023+; use the
argon2npm package in Node.js.
Pitfall: hash passwords in the service layer, not in a model hook — double-hashing can occur if the hook re-runs when other fields are updated.