Menu
CoddyTech

Ein Passwort überprüfen

Teil des Abschnitts Authentifizierung und Sicherheit der Node.js-Journey von Coddy. Lektion 2 von 17.

Ein Hash lässt sich nicht umkehren, deshalb wird beim Anmelden das gespeicherte Passwort niemals ausgelesen. Du hasht den Anmeldeversuch auf dieselbe Weise und vergleichst die beiden Schlüssel. Dieselbe Weise bedeutet dasselbe Salt: Teile das gespeicherte salt:hash auf und verwende sein Salt erneut.

Vergleiche mit timingSafeEqual, nicht mit ===. === bricht beim ersten abweichenden Byte ab, sodass ein Angreifer, der viele Antworten zeitlich misst, erfährt, wie viel eines Rates richtig war. timingSafeEqual benötigt immer dieselbe Zeit. Es vergleicht zwei Buffer gleicher Länge und löst einen Fehler aus, wenn sich die Längen unterscheiden.

import { timingSafeEqual } from 'node:crypto';

const expected = Buffer.from(process.env.API_KEY);
const given = Buffer.from(req.get('x-api-key') ?? '');
const ok = given.length === expected.length && timingSafeEqual(given, expected);

Buffer.from(hex, 'hex') wandelt Hexadezimaltext zurück in Bytes um.

challenge icon

Aufgabe

Einfach
  • Füge in passwords.js verifyPassword(password, stored) hinzu und exportiere es: wahr, wenn das Passwort den gespeicherten Wert erzeugt hat.
  • Füge in server.js POST /login mit { username, password } hinzu: 200 { username } oder 401 { "error": "Wrong username or password" } bei einem falschen Passwort oder einem unbekannten Namen.

Registriere ada, melde dich an und melde dich dann mit einem falschen Passwort an.

Probier es selbst

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

const scryptAsync = promisify(scrypt);

// Wandelt ein Passwort in den Text um, den signup speichert.
export async function hashPassword(password) {
    const salt = randomBytes(16).toString('hex');
    const key = await scryptAsync(password, salt, 64);
    return `${salt}:${key.toString('hex')}`;
}

Alle Lektionen in Authentifizierung und Sicherheit