h4nto
h4nto•2mo ago

issue with verifying password

i tried to look at the docs and source code of the password provider and tried this action to validate the password but i am getting an error: Uncaught ReferenceError: crypto is not defined
No description
12 Replies
sshader
sshader•2mo ago
Is this action running in the Convex runtime? Or in Node? (does it have "use node" at the top of the file) I think Scrypt should work in the Convex runtime, but not sure about Node
h4nto
h4ntoOP•2mo ago
oh thank you, that was the issue, now it works. but another issue comes because it doesn't work as expected. the hash function creates a different secret than the one created on user signup and stored in the db so the verify call fails and that's because the hash function creates a new secret every time it gets called, but then how can someone verify the password? and what's the verify function for
FleetAdmiralJakob 🗕 🗗 🗙
A hash should create the same hash with the same input. Different input, different hash
h4nto
h4ntoOP•2mo ago
i logged this three times in a row consecutive to each other and all of them where different
No description
h4nto
h4ntoOP•2mo ago
literally even trying to hash an hardcoded string returns 4 different hashes
No description
FleetAdmiralJakob 🗕 🗗 🗙
@h4nto I think the reason is the salting. Every hash gets a different salt. For you to get the same hash you would need to give all the same salt
h4nto
h4ntoOP•2mo ago
but how can i customise the salting of the password in the password provider? i searched in the docs and the source code but cannot find it
FleetAdmiralJakob 🗕 🗗 🗙
const scrypt = require('scrypt-js');
const crypto = require('crypto');

// Hash a password with a random salt
async function hashWithScrypt(password) {
const salt = crypto.randomBytes(16); // Generate random salt
const passwordBuffer = Buffer.from(password);

// Hash the password with scrypt
return new Promise((resolve, reject) => {
scrypt(passwordBuffer, salt, 16384, 8, 1, 64, (error, derivedKey) => {
if (error) reject(error);
// Combine salt and derived key for storage (Base64 encoding)
const combined = Buffer.concat([salt, Buffer.from(derivedKey)]).toString('base64');
resolve(combined);
});
});
}

// Verify the password against the stored hash
async function verifyWithScrypt(password, storedHash) {
const decoded = Buffer.from(storedHash, 'base64');
const salt = decoded.slice(0, 16); // Extract salt
const storedKey = decoded.slice(16); // Extract stored key
const passwordBuffer = Buffer.from(password);

// Hash the input password with the same salt
return new Promise((resolve, reject) => {
scrypt(passwordBuffer, salt, 16384, 8, 1, 64, (error, derivedKey) => {
if (error) reject(error);
// Compare derived key with stored key
resolve(Buffer.from(derivedKey).equals(storedKey));
});
});
}

// Example usage
(async () => {
const password = "my_secure_password";
const hash = await hashWithScrypt(password);
console.log("Stored Hash:", hash);

const isValid = await verifyWithScrypt(password, hash);
console.log("Password Valid:", isValid); // Should print: true
})();
const scrypt = require('scrypt-js');
const crypto = require('crypto');

// Hash a password with a random salt
async function hashWithScrypt(password) {
const salt = crypto.randomBytes(16); // Generate random salt
const passwordBuffer = Buffer.from(password);

// Hash the password with scrypt
return new Promise((resolve, reject) => {
scrypt(passwordBuffer, salt, 16384, 8, 1, 64, (error, derivedKey) => {
if (error) reject(error);
// Combine salt and derived key for storage (Base64 encoding)
const combined = Buffer.concat([salt, Buffer.from(derivedKey)]).toString('base64');
resolve(combined);
});
});
}

// Verify the password against the stored hash
async function verifyWithScrypt(password, storedHash) {
const decoded = Buffer.from(storedHash, 'base64');
const salt = decoded.slice(0, 16); // Extract salt
const storedKey = decoded.slice(16); // Extract stored key
const passwordBuffer = Buffer.from(password);

// Hash the input password with the same salt
return new Promise((resolve, reject) => {
scrypt(passwordBuffer, salt, 16384, 8, 1, 64, (error, derivedKey) => {
if (error) reject(error);
// Compare derived key with stored key
resolve(Buffer.from(derivedKey).equals(storedKey));
});
});
}

// Example usage
(async () => {
const password = "my_secure_password";
const hash = await hashWithScrypt(password);
console.log("Stored Hash:", hash);

const isValid = await verifyWithScrypt(password, hash);
console.log("Password Valid:", isValid); // Should print: true
})();
h4nto
h4ntoOP•2mo ago
isn't that verify the same as this? i mean, there is no documentation or anything about that, but i found the source code using this so i suppose it's the right one
No description
h4nto
h4ntoOP•2mo ago
but doesnt seem to work correctly it's using Scrypt from lucia
h4nto
h4ntoOP•2mo ago
the first is what they use when creating an account or updating a password. the second one is what's supposed to be used to verify password
No description
h4nto
h4ntoOP•2mo ago
i'm using their code but doesn't seem to work

Did you find this page helpful?