Hash
Hash script
Hash
export async function hashPassword(password: string) {
const iterations = 10000; // Increase iterations for better security
const digest = 'SHA-512'; // Use stronger default hash
const salt = new Uint8Array(16); // Use larger salt size (32 bytes)
console.log(salt, 'salt during hashPassword before getRandomValues');
crypto.getRandomValues(salt); // Use get random values
console.log(salt, 'salt during hashPassword after getRandomValues');
const importKey = await crypto.subtle.importKey("raw", salt, { name: "PBKDF2" }, false, ["deriveKey"]);
const derivedKey = await crypto.subtle.deriveKey({
name: "PBKDF2",
salt: salt,
iterations: iterations,
hash: digest,
}, importKey, { name: "HMAC", hash: digest, length: 512 }, true, ["sign"]);
const signature = await crypto.subtle.sign({ name: "HMAC" , hash: digest }, derivedKey, new TextEncoder().encode(password));
// Convert signature (ArrayBuffer) to a Uint8Array (has length property)
const signatureArray = new Uint8Array(signature);
console.log(signatureArray, 'signatureArray hashPassword');
const hashString = Array.from(signatureArray).map(b => b.toString(16).padStart(2, '0')).join(''); // Convert to hex string
const saltString = Array.from(salt).map(b => b.toString(16).padStart(2, '0')).join('');
console.log(saltString, hashString, 'hashString')
return {saltString, hashString };
}
export async function verifyPassword(password: string, salt: string, storedHash: string) {
if (salt.length < 1) {
console.log("Salt does not exist");
return false;
}
console.log(password, salt, storedHash, 'password, salt, storedHash')
const iterations = 10000;
const digest = 'SHA-512';
const saltArray = new Uint8Array(salt.length / 2);
for (let i = 0; i < salt.length; i += 2) {
saltArray[i / 2] = parseInt(salt.substring(i, i + 2), 16);
}
// const saltArray = new Uint8Array(salt.split('').map(c => parseInt(c, 16)));
console.log("saltArray verify password", saltArray, salt, 'salt')
const importKey = await crypto.subtle.importKey("raw", saltArray, { name: "PBKDF2" }, false, ["deriveKey"]);
const derivedKey = await crypto.subtle.deriveKey({
name: "PBKDF2",
salt: saltArray,
iterations: iterations,
hash: digest,
}, importKey, { name: "HMAC", hash: digest, length: 512 }, true, ["sign"]);
const signature = await crypto.subtle.sign({ name: "HMAC", hash: digest }, derivedKey, new TextEncoder().encode(password));
// Convert signature (ArrayBuffer) to a Uint8Array (has length property)
const signatureArray = new Uint8Array(signature);
console.log(signatureArray, 'signatureArray verify password');
const generatedHash = Array.from(signatureArray).map(b => b.toString(16).padStart(2, '0')).join('');
console.log(generatedHash, 'generatedHash')
console.log(storedHash, 'storedHash')
if (generatedHash.length < 1) {
console.log("generatedHash does not exist");
throw new Error("generatedHash does not exist");
}
if (storedHash.length < 1) {
console.log("storedHash does not exist");
return new Error("storedHash does not exist");
}
if (generatedHash !== storedHash) {
console.log("Passwords do not match");
return false;
}
return true;
}