Mid #security#bcrypt#argon2#crypto
Hash password trong Node.js: bcrypt/argon2 và timing attack
⚡ Trả lời nhanh
Lưu password bằng hàm hash chậm có salt riêng (argon2id hoặc bcrypt), không dùng SHA/MD5 thuần. So sánh secret/token bằng crypto.timingSafeEqual để tránh timing attack. Hash chạy trên thread pool của libuv nên dùng bản async.
| SHA-256 thuần | bcrypt | argon2id | |
|---|---|---|---|
| Chống brute force GPU | Không | Có (cost factor) | Tốt nhất (memory-hard) |
| Salt | Tự làm | Tự sinh, nhúng trong hash | Tự sinh |
const argon2 = require('argon2');
const crypto = require('node:crypto');
const hash = await argon2.hash(password); // salt nằm trong chuỗi hash
const ok = await argon2.verify(hash, input);
// So sánh token/HMAC: thời gian không phụ thuộc vị trí byte khác nhau
const a = Buffer.from(sigA), b = Buffer.from(sigB);
const same = a.length === b.length && crypto.timingSafeEqual(a, b);
Timing attack: === thoát ngay ở byte đầu tiên khác, nên kẻ tấn công đo thời gian để đoán dần từng byte. timingSafeEqual yêu cầu hai buffer cùng độ dài.