Menu
CoddyTech

Verificare una password

Fa parte della sezione Autenticazione e sicurezza del percorso Node.js di Coddy. Lezione 6 di 24.

Un accesso ricava una chiave dalla password tentata usando il salt salvato e la lunghezza originale della chiave. Un salt nuovo produrrebbe una chiave diversa anche con la password corretta. La password originale non viene mai decodificata dall’archiviazione.

// Un codice di invito è stato memorizzato come salt.keyHex
const [salt, keyHex] = savedInvite.split('.');
const expected = Buffer.from(keyHex, 'hex');
const attempted = await scryptAsync(inviteCode, salt, 32);

Confronta le sequenze di byte risultanti usando timingSafeEqual, dopo aver verificato che le loro lunghezze corrispondano. In questo modo si evita un’uscita anticipata dipendente dal contenuto, che potrebbe rivelare informazioni attraverso i tempi di esecuzione. === di Buffer verifica l’identità, mentre un normale confronto tra stringhe non offre alcuna garanzia di tempo costante. La tua funzione per la password usa il delimitatore dei due punti del record della password e una chiave di 64 byte. La route POST /login che aggiungi usa il risultato per restituire 200 o 401.

challenge icon

Sfida

Facile

Questo passaggio apre il progetto API per le note private preparato per il corso, anziché i file del tuo progetto di Never Store Passwords (incluso passwords.js). Il lavoro precedente rimane nella sua lezione. Leggi i file forniti prima di modificare passwords.js. Questa copia contiene funzioni di supporto per l'hashing delle password e le route di debug fornite.

La registrazione ora salva hash con salt. Aggiungi una procedura di accesso che verifichi una password confrontandola con quella salvata durante la registrazione.

  1. In passwords.js, aggiungi ed esporta una funzione async verifyPassword(password, stored). stored è un valore salvato durante la registrazione, come f2bb...f065:c3f7...dbd2. Restituisci true quando password è la password che lo ha generato e false altrimenti:
    • Prendi il salt che precede i due punti.
    • Calcola l'hash di password con quel salt, ottenendo una chiave di 64 byte, nello stesso modo in cui fa hashPassword.
    • Decodifica in esadecimale la chiave salvata dopo i due punti. Se le lunghezze in byte delle due chiavi sono diverse, restituisci false senza chiamare timingSafeEqual, come in Comparing Key Bytes. Altrimenti restituisci il risultato del confronto.
  2. In server.js, importa verifyPassword accanto a hashPassword. Aggiungi POST /login. Riceve lo stesso corpo della registrazione, per esempio {"username": "ada", "password": "correct horse"}.
    • Cerca l'utente con quel nome utente. verifyPassword è lenta e restituisce una promise, quindi attendine il completamento.
    • Se l'utente esiste e la password è corretta, rispondi con stato 200 e {"username": "ada"}.
    • Altrimenti, rispondi con stato 401 e {"error": "Wrong username or password"}. 401 Unauthorized significa che la richiesta non ha dimostrato chi la sta inviando.
    • Invia lo stesso 401 sia per una password errata sia per un nome utente con cui nessuno si è registrato. In questo modo, il corpo della risposta non rivela mai a nessuno quali nomi utente esistono.

Prova: premi Esegui. Invia POST /signup con {"username": "ada", "password": "correct horse"}: stato 201. Invia POST /login con lo stesso corpo: stato 200 e {"username": "ada"}. Invia POST /login con {"username": "ada", "password": "wrong horse"}: stato 401 e {"error": "Wrong username or password"}. Invia POST /login con {"username": "nobody", "password": "correct horse"}: lo stesso 401.

Provalo tu

import { randomBytes, scrypt } from 'node:crypto';
import { promisify } from 'node:util';

const scryptAsync = promisify(scrypt);

// Converte una password nel testo che signup memorizza.
export async function hashPassword(password) {
    const salt = randomBytes(16).toString('hex');
    const key = await scryptAsync(password, salt, 64);
    return `${salt}:${key.toString('hex')}`;
}

Tutte le lezioni di Autenticazione e sicurezza

Esercitati da solo: Playground Express