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;
}