The scrypt password-based key derivation function with sync and cancellable async.
npx @tessl/cli install tessl/npm-scrypt-js@3.0.0scrypt-js is a JavaScript implementation of the scrypt password-based key derivation function (PBKDF) designed for brute-force resistance. It provides both synchronous and asynchronous computation methods with advanced features including non-blocking execution, cancellable operations, and progress callbacks for real-time feedback during key derivation.
npm install scrypt-jsconst scrypt = require("scrypt-js");TypeScript/ES6:
import * as scrypt from "scrypt-js";
// or
import { scrypt as scryptAsync, syncScrypt } from "scrypt-js";const scrypt = require("scrypt-js");
// Convert password and salt to byte arrays
const password = Buffer.from("myPassword", "utf8");
const salt = Buffer.from("mySalt", "utf8");
// Set scrypt parameters
const N = 1024; // CPU/memory cost
const r = 8; // Block size
const p = 1; // Parallelization
const dkLen = 32; // Desired key length
// Asynchronous with progress callback
const progressCallback = (progress) => {
console.log(`Progress: ${Math.round(progress * 100)}%`);
// Return true to cancel operation
return false;
};
scrypt.scrypt(password, salt, N, r, p, dkLen, progressCallback)
.then(key => {
console.log("Derived key:", Buffer.from(key).toString("hex"));
})
.catch(error => {
console.error("Error:", error);
});
// Synchronous (blocking)
const key = scrypt.syncScrypt(password, salt, N, r, p, dkLen);
console.log("Derived key:", Buffer.from(key).toString("hex"));Computes the scrypt PBKDF asynchronously using a Promise, allowing for non-blocking execution and progress monitoring.
function scrypt(
password: ArrayLike<number>,
salt: ArrayLike<number>,
N: number,
r: number,
p: number,
dkLen: number,
callback?: ProgressCallback
): Promise<Uint8Array>;Parameters:
password: Password as byte array (ArrayLike<number>)salt: Salt as byte array (ArrayLike<number>)N: CPU/memory cost parameter (must be power of 2)r: Block size parameterp: Parallelization parameterdkLen: Desired key length in bytescallback: Optional callback for progress updates and cancellationReturns: Promise that resolves to Uint8Array containing the derived key
Features:
true from progress callback (Promise rejects when cancelled)Computes the scrypt PBKDF synchronously, blocking execution until completion.
function syncScrypt(
password: ArrayLike<number>,
salt: ArrayLike<number>,
N: number,
r: number,
p: number,
dkLen: number
): Uint8Array;Parameters:
password: Password as byte array (ArrayLike<number>)salt: Salt as byte array (ArrayLike<number>)N: CPU/memory cost parameter (must be power of 2)r: Block size parameterp: Parallelization parameterdkLen: Desired key length in bytesReturns: Uint8Array containing the derived key
Note: This function blocks the JavaScript event loop during computation and is not recommended for UI applications.
type ProgressCallback = (progress: number) => boolean | void;ProgressCallback function:
progress: Number between 0 and 1 (inclusive) indicating completion percentagetrue to cancel the operation, false or undefined to continueThe scrypt algorithm uses three tuning parameters that affect security and performance:
Important: Always normalize Unicode passwords using String.prototype.normalize('NFKC') before converting to bytes to ensure consistent results across platforms.
// Recommended password encoding
const password = Buffer.from("myPassword".normalize('NFKC'), "utf8");
const salt = Buffer.from("mySalt".normalize('NFKC'), "utf8");// Async error handling
scrypt.scrypt(password, salt, N, r, p, dkLen)
.then(key => {
// Success
})
.catch(error => {
// Handle errors (invalid parameters, out of memory, etc.)
});
// Sync error handling
try {
const key = scrypt.syncScrypt(password, salt, N, r, p, dkLen);
} catch (error) {
// Handle errors
}String.prototype.normalize() support or polyfill (unorm package)scrypt) for UI applications to avoid blockingsyncScrypt) only for server-side or CLI applications