Last active
February 6, 2025 23:26
-
-
Save SafeEval/4adac213bc0829eb42a107df380a823d to your computer and use it in GitHub Desktop.
Example of using Scrypt hashing in TypeScript.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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