33 lines
1.2 KiB
TypeScript
33 lines
1.2 KiB
TypeScript
import { createHash, pbkdf2Sync } from "node:crypto";
|
|
|
|
export function sha256(data: Uint8Array | string): Uint8Array {
|
|
const hash = createHash("sha256");
|
|
hash.update(data);
|
|
return new Uint8Array(hash.digest());
|
|
}
|
|
|
|
export function deriveKey(password: string, salt: Uint8Array, rounds: number, length = 32): Uint8Array {
|
|
if (!Number.isFinite(rounds) || rounds <= 0) {
|
|
throw new Error("Invalid key derivation rounds");
|
|
}
|
|
|
|
return new Uint8Array(pbkdf2Sync(password, Buffer.from(salt), rounds, length, "sha256"));
|
|
}
|
|
|
|
export function normalizeKeyFileBytes(bytes: Uint8Array): Uint8Array {
|
|
return sha256(bytes);
|
|
}
|
|
|
|
export function combineSecrets(password: string, keyFileBytes?: Uint8Array): Uint8Array {
|
|
const passwordHash = sha256(password);
|
|
if (!keyFileBytes) return passwordHash;
|
|
return sha256(Buffer.concat([Buffer.from(passwordHash), Buffer.from(normalizeKeyFileBytes(keyFileBytes))]));
|
|
}
|
|
|
|
export function deriveMasterKey(secret: Uint8Array, salt: Uint8Array, rounds: number): Uint8Array {
|
|
if (secret.length === 0) {
|
|
throw new Error("Missing secret for key derivation");
|
|
}
|
|
return new Uint8Array(pbkdf2Sync(Buffer.from(secret), Buffer.from(salt), rounds, 32, "sha256"));
|
|
}
|