Skip to content

Instantly share code, notes, and snippets.

@SafeEval
Last active February 6, 2025 23:26
Show Gist options
  • Save SafeEval/4adac213bc0829eb42a107df380a823d to your computer and use it in GitHub Desktop.
Save SafeEval/4adac213bc0829eb42a107df380a823d to your computer and use it in GitHub Desktop.
Example of using Scrypt hashing in TypeScript.
import { randomBytes as csprngRandomBytes, scrypt, timingSafeEqual } from 'crypto';
import { promisify } from 'util';
const scryptAsync = promisify(scrypt);
/**
* Hashes a string using the scrypt algorithm.
*
* @param value - The value to hash.
* @returns A promise that resolves to the hashed value in the format `base64(salt):base64(derivedKey)`.
*/
export async function scryptHash(value: string): Promise<string> {
const salt = csprngRandomBytes(16);
const keylen = 64;
const derivedKey = await scryptAsync(value, salt, keylen) as Buffer;
const derivedKeyB64 = derivedKey.toString('base64url');
const saltB64 = salt.toString('base64url');
return `${saltB64}:${derivedKeyB64}`;
}
/**
* Verifies a string against a scrypt hash.
*
* @param expectedHash - The hashed value to compare against in the format `base64(salt):base64(derivedKey)`.
* @param submittedValue - The plaintext value to recalculate and verify.
* @returns A promise that resolves to true if the value is verified, false otherwise.
*/
export async function scryptVerify(expectedHash: string, submittedValue: string): Promise<boolean> {
const [saltB64, expectedKeyB64] = expectedHash.split(':');
const salt = Buffer.from(saltB64, 'base64url');
const expectedKey = Buffer.from(expectedKeyB64, 'base64url');
const actualKey = await scryptAsync(submittedValue, salt, 64) as Buffer;
return timingSafeEqual(expectedKey, actualKey);
}
async function main() {
const hash = await scryptHash('password');
console.log(`Resulting hash: ${hash}`);
const goodMatch = await scryptVerify(hash, 'password');
console.log(`Good match: ${goodMatch}`);
const badMatch = await scryptVerify(hash, 'wrong-password');
console.log(`Bad match: ${badMatch}`);
}
main();
$ npx tsx scrypt-example.ts
Resulting hash: V1MrNbV-hNT8BjyPhTLIMw:rRIV0X2WR7tHdcJ6O8KR_H1rduSK098wNH0gfOOKaYtDvc4-1NYql3WSdAzgm8RRjfHnoc5AKnihW00TRhI3RA
Good match: true
Bad match: false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment