async function login(user, password) {
const isCorrect = await verifyHash(password, user.hash);
if (!isCorrect) throw new Error('Invalid credentials');
// Daca e inca pe bcrypt, facem upgrade transparent
if (user.hashAlgorithm === 'bcrypt') {
const newHash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 65536,
timeCost: 3,
parallelism: 4
});
await db.users.update(user.id, {
hash: newHash,
hashAlgorithm: 'argon2id'
});
console.log(`User ${user.id} migrated to Argon2id`);
}
return createSession(user);
}Să fim sinceri, majoritatea am rămas blocați pe bcrypt dintr-o inerție care începe să devină periculoasă. Am avut recent un audit pe un proiect cu vreo 80.000 de useri activi și am descoperit că foloseau bcrypt cu un cost factor de 10, setat prin 2018 și uitat acolo. În 2026, dacă nu ai trecut deja pe Argon2id, ești deja în urmă, dar vestea bună e că nu trebuie să faci o migrare de tip „big bang” care să-ți pună baza de date în cap.
De ce ne batem capul cu Argon2id?
Problema cu bcrypt nu e că ar fi „spart” în sensul matematic, ci că e vulnerabil la atacuri cu hardware specializat (FPGA-uri și ASIC-uri). Bcrypt consumă doar putere de procesare, pe când Argon2id, câștigătorul Password Hashing Competition, este „memory-hard”. Asta înseamnă că forțează atacatorul să folosească multă memorie RAM, ceea ce face atacurile brute-force masive mult mai scumpe și mai greu de scalat.
La un proiect anterior, am făcut trecerea de la bcrypt la Argon2id și am observat o creștere de aproximativ 15% în latența de login, dar am câștigat o rezistență de zece ori mai mare la atacuri offline. Trade-off-ul e clar: sacrifici un pic de RAM pe server ca să dormi liniștit noaptea. Totuși, atenție la containerele de Docker mici; dacă ai limitat RAM-ul la 256MB și vrei să rulezi Argon2id cu setări agresive, s-ar putea să te trezești cu OOM (Out Of Memory) la fiecare încercare de login.
Cost factor și parametri reali în 2026
Dacă încă ești pe bcrypt, costul de 10 e istorie. În 2026, un cost factor de 12 ar trebui să fie minimul absolut, vizând un timp de hashing de aproximativ 250-500ms pe hardware-ul tău de producție. Mai puțin de atât e prea ușor de atacat, mai mult de atât și începi să enervezi userii la login.
Pentru Argon2id, nu te uita doar la o singură cifră. Ai trei parametri: m (memorie), t (iterații) și p (paralelism). O configurație de plecare rezonabilă acum este m=64MB, t=3, p=4. Dar nu mă crede pe cuvânt. Rulează un benchmark pe mașina de producție. Dacă login-ul durează 10ms, ești „pâine prăjită” în fața unui cluster de GPU-uri.
Cum migrăm fără să resetăm parolele tuturor?
Cea mai proastă idee pe care am auzit-o a fost „hai să exportăm tot, să decriptăm și să re-hash-uim”. Evident, nu poți decripta hash-urile. Soluția corectă este migrarea graduală la login (Lazy Migration).
Logica e simplă: când userul se loghează, verifici mai întâi hash-ul cu algoritmul vechi (bcrypt). Dacă parola e corectă, generezi imediat un hash nou folosind Argon2id și îl suprascrii în baza de date. În paralel, adaugi o coloană în DB care să specifice ce algoritm a fost folosit pentru acel rând.
Am aplicat schema asta pe o platformă e-commerce și, în primele 48 de ore, am migrat peste 60% din userii activi fără niciun downtime sau sesiune expirată forțat. Ce facem cu restul de 40% care nu se loghează niciodată? Îi lăsăm acolo. Dacă baza de date e furată peste 2 ani, măcar userii activi sunt protejați de noul standard.
Concluzie
Bcrypt încă „merge”, dar e ca și cum ai conduce o mașină fără airbag-uri laterale în 2026. E ok până la primul impact. Trecerea la Argon2id nu e un moft de securitate, ci o adaptare necesară la cât de ieftin a devenit hash-cracking-ul pe GPU.
Voi ce setări de cost folosiți în producție și cât de mult v-a afectat latența la login?