hash pasword types fix
This commit is contained in:
@@ -13,8 +13,8 @@ describe("hashPassword", () => {
|
||||
expect(parts[1]).toBe("pbkdf2-sha256");
|
||||
expect(parts[2]).toBe("100000");
|
||||
// Salt and hash should be non-empty base64 strings
|
||||
expect(parts[3].length).toBeGreaterThan(0);
|
||||
expect(parts[4].length).toBeGreaterThan(0);
|
||||
expect(parts[3]?.length).toBeGreaterThan(0);
|
||||
expect(parts[4]?.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should generate different hashes for the same password", async () => {
|
||||
@@ -98,4 +98,66 @@ describe("verifyPassword", () => {
|
||||
const wrongResult = await verifyPassword("password", hash);
|
||||
expect(wrongResult).toBe(false);
|
||||
});
|
||||
|
||||
it("should verify known hash for 'password'", async () => {
|
||||
// This hash was generated for the password "password"
|
||||
const storedHash =
|
||||
"$pbkdf2-sha256$100000$iUaDbbVm+Mf0HG7RcCCOzw==$IQfBN4chRU3wqCEoC9XOusIVYkyW24dbJd/ksm0VBJk=";
|
||||
const password = "password";
|
||||
|
||||
const result = await verifyPassword(password, storedHash);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should derive consistent hash for known salt and password", async () => {
|
||||
// Manually verify the derivation produces the expected hash
|
||||
const password = "password";
|
||||
const saltB64 = "iUaDbbVm+Mf0HG7RcCCOzw==";
|
||||
const expectedHashB64 = "IQfBN4chRU3wqCEoC9XOusIVYkyW24dbJd/ksm0VBJk=";
|
||||
const iterations = 100000;
|
||||
|
||||
// Decode salt
|
||||
const saltBinary = atob(saltB64);
|
||||
const salt = new Uint8Array(saltBinary.length);
|
||||
for (let i = 0; i < saltBinary.length; i++) {
|
||||
salt[i] = saltBinary.charCodeAt(i);
|
||||
}
|
||||
|
||||
// Derive key
|
||||
const encoder = new TextEncoder();
|
||||
const passwordBuffer = encoder.encode(password);
|
||||
|
||||
const keyMaterial = await crypto.subtle.importKey(
|
||||
"raw",
|
||||
passwordBuffer,
|
||||
"PBKDF2",
|
||||
false,
|
||||
["deriveBits"],
|
||||
);
|
||||
|
||||
const derivedBits = await crypto.subtle.deriveBits(
|
||||
{
|
||||
name: "PBKDF2",
|
||||
salt,
|
||||
iterations,
|
||||
hash: "SHA-256",
|
||||
},
|
||||
keyMaterial,
|
||||
32 * 8,
|
||||
);
|
||||
|
||||
// Encode result to base64
|
||||
const derivedArray = new Uint8Array(derivedBits);
|
||||
let binary = "";
|
||||
for (const byte of derivedArray) {
|
||||
binary += String.fromCharCode(byte);
|
||||
}
|
||||
const derivedB64 = btoa(binary);
|
||||
|
||||
console.log("Expected hash:", expectedHashB64);
|
||||
console.log("Derived hash: ", derivedB64);
|
||||
console.log("Match:", derivedB64 === expectedHashB64);
|
||||
|
||||
expect(derivedB64).toBe(expectedHashB64);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -107,6 +107,7 @@ export const verifyPassword = async (
|
||||
const derivedBits = await crypto.subtle.deriveBits(
|
||||
{
|
||||
name: "PBKDF2",
|
||||
// @ts-expect-error - salt is a Uint8Array
|
||||
salt,
|
||||
iterations,
|
||||
hash: "SHA-256",
|
||||
|
||||
Reference in New Issue
Block a user