Files
craftvia/scripts/test-password-pepper.ts
T
msolarczekandClaude Opus 5 c8e6f30a27
CI / build-and-check (push) Canceled after 0s
CI / audit (push) Canceled after 0s
CI / sbom (push) Canceled after 0s
Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation
und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 11:05:39 +02:00

60 lines
2.3 KiB
TypeScript

// Härtung §1 — Pepper-Abnahmetest.
//
// Weist nach, dass der PASSWORD_PEPPER tatsächlich in Argon2-Hash UND -Verify eingeht:
// 1. hashPassword+verifyPassword (beide peppered) → true.
// 2. Verify OHNE Pepper (roher argon2) gegen einen peppered Hash → false.
// 3. Verify mit FALSCHEM Pepper → false.
// 4. Falsches Passwort mit korrektem Pepper → false.
// 5. Recovery-Codes (mfa.ts nutzt hashPassword/verifyPassword) matchen mit Pepper.
//
// Lauf: npx tsx scripts/test-password-pepper.ts (PASSWORD_PEPPER muss gesetzt sein)
import "dotenv/config";
import { verify as rawVerify } from "@node-rs/argon2";
import { hashPassword, verifyPassword } from "../src/server/password";
import { generateRecoveryCodes, matchRecovery } from "../src/server/mfa";
let failures = 0;
const ok = (cond: boolean, msg: string) => {
console.log(`${cond ? "✓" : "✗ FEHLER"} ${msg}`);
if (!cond) failures++;
};
const PW = "Pepper-Test-Passwort-1!";
async function main() {
ok(/^[0-9a-fA-F]{64}$/.test(process.env.PASSWORD_PEPPER ?? ""), "PASSWORD_PEPPER ist gesetzt (32-Byte hex)");
const h = await hashPassword(PW);
console.log("\n— 1) korrekter Pepper —");
ok(await verifyPassword(h, PW), "verifyPassword mit korrektem Pepper → true");
console.log("\n— 2/3) fehlender / falscher Pepper —");
ok((await rawVerify(h, PW).catch(() => false)) === false, "verify OHNE Pepper → false (Pepper geht wirklich in den Hash)");
const wrongPepper = Buffer.alloc(32, 0x11);
ok((await rawVerify(h, PW, { secret: wrongPepper }).catch(() => false)) === false, "verify mit FALSCHEM Pepper → false");
console.log("\n— 4) falsches Passwort —");
ok((await verifyPassword(h, "falsch!!")) === false, "falsches Passwort (korrekter Pepper) → false");
console.log("\n— 5) Recovery-Codes mit Pepper —");
const { plain, hashed } = await generateRecoveryCodes(3);
ok((await matchRecovery(plain[0]!, hashed)) === 0, "gültiger Recovery-Code matcht (peppered hash/verify)");
ok((await matchRecovery("000-000", hashed)) === -1, "ungültiger Recovery-Code matcht nicht");
}
main()
.then(() => {
if (failures > 0) {
console.error(`\n✗ ${failures} Testfall/-fälle fehlgeschlagen.`);
process.exit(1);
}
console.log("\nOK");
process.exit(0);
})
.catch((e) => {
console.error(e);
process.exit(1);
});