Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: use async
  • Loading branch information
G3root committed Aug 7, 2024
commit ebeee1656fa64fa0588a843574260fc12330608b
42 changes: 34 additions & 8 deletions src/lib/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { randomBytes, scryptSync, subtle } from "node:crypto";
import {
type BinaryLike,
randomBytes,
scrypt,
subtle,
timingSafeEqual,
} from "node:crypto";
import { customId } from "@/common/id";

export const createHash = async (key: string) => {
Expand All @@ -25,18 +31,38 @@ export const initializeAccessToken = ({
};
};

export const createSecureHash = (secret: string) => {
const scryptAsync = (
password: BinaryLike,
salt: BinaryLike,
keylen: number,
): Promise<Buffer> => {
return new Promise((resolve, reject) => {
scrypt(password, salt, keylen, (err, derivedKey) => {
if (err) reject(err);
else resolve(derivedKey);
});
});
};

export const createSecureHash = async (secret: string) => {
const data = new TextEncoder().encode(secret);
const salt = randomBytes(32).toString("hex");
const derivedKey = scryptSync(data, salt, 64);
const derivedKey = await scryptAsync(data, salt, 64);

return `${salt}:${derivedKey.toString("hex")}`;
};

export const verifySecureHash = (secret: string, hash: string) => {
const data = new TextEncoder().encode(secret);
const [salt, storedHash] = hash.split(":");
const derivedKey = scryptSync(data, String(salt), 64);
export const verifySecureHash = async (secret: string, hash: string) => {
try {
const data = new TextEncoder().encode(secret);
const [salt, storedHash] = hash.split(":");

const derivedKey = await scryptAsync(data, salt ?? "", 64);

return storedHash === derivedKey.toString("hex");
const derivedKeyBuffer = Buffer.from(derivedKey);
const storedHashBuffer = Buffer.from(storedHash ?? "", "hex");
return timingSafeEqual(derivedKeyBuffer, storedHashBuffer);
} catch (_error) {
return false;
}
};