Canopy
Canopy
CDCloudflare Developers
Created by Canopy on 3/9/2024 in #workers-help
Secure Hashing of Passwords in Workers
Working on a project where I want to salt and hash passwords using cloudflare workers, I'm using next-on-pages with Nextjs 14 and this means that I can't access libraries like bcrypt or similar that require os or fs. I have a hacky solution but it's just that, a hacky workaround and while security isn't something I'm fussed about, I would at least like to use a validated salt and hash strategy. If anyone knows any libraries that would work or other solutions please let me know. Here is my hacky solution, this was botched together in a single afternoon so I'm not expecting it to work well but it does the job for now:
static async hashPassword(
password: string,
salt?: string
): Promise<HashedCredentials> {
let saltArray = null;

if (salt) {
saltArray = new TextEncoder().encode(salt);
} else {
saltArray = crypto.getRandomValues(new Uint8Array(16));
}

const saltBuffer = new TextEncoder().encode(saltArray);
const passwordBuffer = new TextEncoder().encode(password);

// Concatenate the password and salt
const concatenatedBuffer = new Uint8Array(
passwordBuffer.byteLength + saltBuffer.byteLength
);
concatenatedBuffer.set(new Uint8Array(passwordBuffer), 0);
concatenatedBuffer.set(
new Uint8Array(saltBuffer),
passwordBuffer.byteLength
);

// Hash the concatenated password and salt
const hashBuffer = await crypto.subtle.digest(
"SHA-256",
concatenatedBuffer
);

// Convert the hash and salt to hexadecimal strings
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
const saltHex = saltArray
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");

return { passwordHash: hashHex, passwordSalt: saltHex };
}
static async hashPassword(
password: string,
salt?: string
): Promise<HashedCredentials> {
let saltArray = null;

if (salt) {
saltArray = new TextEncoder().encode(salt);
} else {
saltArray = crypto.getRandomValues(new Uint8Array(16));
}

const saltBuffer = new TextEncoder().encode(saltArray);
const passwordBuffer = new TextEncoder().encode(password);

// Concatenate the password and salt
const concatenatedBuffer = new Uint8Array(
passwordBuffer.byteLength + saltBuffer.byteLength
);
concatenatedBuffer.set(new Uint8Array(passwordBuffer), 0);
concatenatedBuffer.set(
new Uint8Array(saltBuffer),
passwordBuffer.byteLength
);

// Hash the concatenated password and salt
const hashBuffer = await crypto.subtle.digest(
"SHA-256",
concatenatedBuffer
);

// Convert the hash and salt to hexadecimal strings
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
const saltHex = saltArray
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");

return { passwordHash: hashHex, passwordSalt: saltHex };
}
3 replies
CDCloudflare Developers
Created by Canopy on 12/10/2023 in #pages-help
Next on Pages with Next 14 suddenly produces huge build package.
Just upgraded to Next14 on a project, and now npx @cloudflare/next-on-pages produces a huge 45MB output and I get the Error: Failed to publish your Function. Got error: Your Functions script is over the 1 MiB size limit (workers.api.error.script_too_large) Is this a known issue when switching to Next14, I'm aware it only came out a little bit ago. Or is this something more to do with my project? Also while debugging and building using npx @Not Cloudflare :)/next-on-pages I keep getting asked to log into vercel, but that only happened after a few tries, what's up with that?
6 replies