import crypto from 'node:crypto';
const PASSWORD = '12345678';
const SALT = crypto.randomBytes(16); // unique for each password
const NORMALIZED_PASSWORD = PASSWORD.slice(-128).normalize('NFKC');
console.log('Salt:', SALT.toString('hex'), '\n');
//////////////////////////////////////////////////
// SCRYPT (Node.js v10.9)
//////////////////////////////////////////////////
const hashScryptBuffer = crypto.scryptSync(
NORMALIZED_PASSWORD,
SALT,
64, // keylen
{
N: 16384, // CPU/memory cost
r: 8, // Block size
p: 1 // Parallelization
}
);
const hashScryptHex = hashScryptBuffer.toString('hex');
console.log('Scrypt:', hashScryptHex);
const hashScryptIsEqual = crypto.timingSafeEqual(
Buffer.from(hashScryptHex, 'hex'),
hashScryptBuffer
);
console.log('Verify:', hashScryptIsEqual, '\n');
//////////////////////////////////////////////////
// ARGON2 (Node.js v24.7)
//////////////////////////////////////////////////
const hashArgon2Buffer = crypto.argon2Sync(
'argon2id',
{
message: NORMALIZED_PASSWORD,
nonce: SALT,
parallelism: 4,
tagLength: 64,
memory: 65536,
passes: 3
}
);
const hashArgon2Hex = hashArgon2Buffer.toString('hex');
console.log('Argon2:', hashArgon2Hex);
const hashArgon2IsEqual = crypto.timingSafeEqual(
Buffer.from(hashArgon2Hex, 'hex'),
hashArgon2Buffer
);
console.log('Verify:', hashArgon2IsEqual);Internet standard for creating data with optional signature whose payload holds JSON that asserts some number of claims.
import crypto from 'node:crypto';
// Base 64 Encoding with URL and Filename Safe Alphabet.
function toBase64Url(data) {
if (Buffer.isBuffer(data))
return data.toString('base64url');
if (typeof(data) !== 'string')
data = JSON.stringify(data);
return toBase64Url(Buffer.from(data));
}
function fromBase64Url(data, parseJson) {
data = Buffer.from(data, 'base64url');
if (parseJson != null)
data = data.toString('utf8');
return parseJson ? JSON.parse(data) : data;
}
//////////////////////////////////////////////////
// JWT: HEADER & PAYLOAD
//////////////////////////////////////////////////
// RSA PKCS1-v1.5 (1993).
//
// RSA: Rivest–Shamir–Adleman
// PKCS1: Public Key Cryptography Standard #1
const ALG = 'RS256'; // 'RS256' | 'RS384' | 'RS512'
const ALGORITHM = 'SHA256'; // 'SHA256' | 'SHA384' | 'SHA512'
const header = { alg: ALG, typ: 'JWT' };
const payload = { data: 'Hello World!' };
//////////////////////////////////////////////////
// KEYS
//////////////////////////////////////////////////
const { publicKey, privateKey } = crypto.generateKeyPairSync(
'rsa',
{
modulusLength: 3072, // ≥2048
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
},
}
);
const PADDING = crypto.constants.RSA_PKCS1_PADDING;
const PUBLIC_KEY = { key: publicKey, padding: PADDING };
const PRIVATE_KEY = { key: privateKey, padding: PADDING };
console.log(`publicKey:\n${publicKey}`);
//////////////////////////////////////////////////
// SIGN
//////////////////////////////////////////////////
const headerBase64Url = toBase64Url(header);
const payloadBase64Url = toBase64Url(payload);
const data = `${headerBase64Url}.${payloadBase64Url}`;
const signature = crypto.sign(ALGORITHM, data, PRIVATE_KEY);
const signatureBase64Url = toBase64Url(signature);
const jsonWebToken = `${data}.${signatureBase64Url}`;
console.log('Token:', jsonWebToken, '\n');
//////////////////////////////////////////////////
// VERIFY
//////////////////////////////////////////////////
const jwtParts = jsonWebToken.split('.');
const jwtHeaderBase64Url = jwtParts[0];
const jwtPayloadBase64Url = jwtParts[1];
const jwtSignatureBase64Url = jwtParts[2];
const jwtHeaderObject = fromBase64Url(jwtHeaderBase64Url, true);
const jwtPayloadObject = fromBase64Url(jwtPayloadBase64Url, true);
const jwtSignatureBuffer = fromBase64Url(jwtSignatureBase64Url);
if (jwtHeaderObject.alg !== header.alg)
throw new Error('Invalid algorithm');
const jwtData = `${jwtHeaderBase64Url}.${jwtPayloadBase64Url}`;
const isValid = crypto.verify(ALGORITHM, jwtData, PUBLIC_KEY, jwtSignatureBuffer);
console.log('Verify:', isValid); // true
console.log('Header:', jwtHeaderObject); // { alg: 'RS256', typ: 'JWT' }
console.log('Payload:', jwtPayloadObject); // { data: 'Hello World!' }import crypto from 'node:crypto';
// Base 64 Encoding with URL and Filename Safe Alphabet.
function toBase64Url(data) {
if (Buffer.isBuffer(data))
return data.toString('base64url');
if (typeof(data) !== 'string')
data = JSON.stringify(data);
return toBase64Url(Buffer.from(data));
}
function fromBase64Url(data, parseJson) {
data = Buffer.from(data, 'base64url');
if (parseJson != null)
data = data.toString('utf8');
return parseJson ? JSON.parse(data) : data;
}
//////////////////////////////////////////////////
// JWT: HEADER & PAYLOAD
//////////////////////////////////////////////////
// RSA-PSS PKCS1-v2.1 (2002)
//
// RSA: Rivest–Shamir–Adleman
// PSS: Probabilistic Signature Scheme
// PKCS1: Public Key Cryptography Standard #1
const ALG = 'PS256'; // 'PS256' | 'PS384' | 'PS512'
const ALGORITHM = 'SHA256'; // 'SHA256' | 'SHA384' | 'SHA512'
const header = { alg: ALG, typ: 'JWT' };
const payload = { data: 'Hello World!' };
//////////////////////////////////////////////////
// KEYS
//////////////////////////////////////////////////
const { publicKey, privateKey } = crypto.generateKeyPairSync(
'rsa',
{
modulusLength: 3072, // ≥2048
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
},
}
);
const PADDING = crypto.constants.RSA_PKCS1_PSS_PADDING; // MGF1
const SALTLENGTH = crypto.constants.RSA_PSS_SALTLEN_DIGEST;
const PUBLIC_KEY = { key: publicKey, padding: PADDING, saltLength: SALTLENGTH };
const PRIVATE_KEY = { key: privateKey, padding: PADDING, saltLength: SALTLENGTH };
console.log(`publicKey:\n${publicKey}`);
//////////////////////////////////////////////////
// SIGN
//////////////////////////////////////////////////
const headerBase64Url = toBase64Url(header);
const payloadBase64Url = toBase64Url(payload);
const data = `${headerBase64Url}.${payloadBase64Url}`;
const signature = crypto.sign(ALGORITHM, data, PRIVATE_KEY);
const signatureBase64Url = toBase64Url(signature);
const jsonWebToken = `${data}.${signatureBase64Url}`;
console.log('Token:', jsonWebToken, '\n');
//////////////////////////////////////////////////
// VERIFY
//////////////////////////////////////////////////
const jwtParts = jsonWebToken.split('.');
const jwtHeaderBase64Url = jwtParts[0];
const jwtPayloadBase64Url = jwtParts[1];
const jwtSignatureBase64Url = jwtParts[2];
const jwtHeaderObject = fromBase64Url(jwtHeaderBase64Url, true);
const jwtPayloadObject = fromBase64Url(jwtPayloadBase64Url, true);
const jwtSignatureBuffer = fromBase64Url(jwtSignatureBase64Url);
if (jwtHeaderObject.alg !== header.alg)
throw new Error('Invalid algorithm');
const jwtData = `${jwtHeaderBase64Url}.${jwtPayloadBase64Url}`;
const isValid = crypto.verify(ALGORITHM, jwtData, PUBLIC_KEY, jwtSignatureBuffer);
console.log('Verify:', isValid); // true
console.log('Header:', jwtHeaderObject); // { alg: 'PS256', typ: 'JWT' }
console.log('Payload:', jwtPayloadObject); // { data: 'Hello World!' }import crypto from 'node:crypto';
// Base 64 Encoding with URL and Filename Safe Alphabet.
function toBase64Url(data) {
if (Buffer.isBuffer(data))
return data.toString('base64url');
if (typeof(data) !== 'string')
data = JSON.stringify(data);
return toBase64Url(Buffer.from(data));
}
function fromBase64Url(data, parseJson) {
data = Buffer.from(data, 'base64url');
if (parseJson != null)
data = data.toString('utf8');
return parseJson ? JSON.parse(data) : data;
}
//////////////////////////////////////////////////
// JWT: HEADER & PAYLOAD
//////////////////////////////////////////////////
// Elliptic Curve Digital Signature Algorithm (ECDSA)
const ALG = 'ES256'; // 'ES256' | 'ES384' | 'ES512'
const NAMED_CURVE = 'P-256'; // 'P-256' | 'P-384' | 'P-512'
const ALGORITHM = 'SHA256'; // 'SHA256' | 'SHA384' | 'SHA512'
const header = { alg: ALG, typ: 'JWT' };
const payload = { data: 'Hello World!' };
//////////////////////////////////////////////////
// KEYS
//////////////////////////////////////////////////
const { publicKey, privateKey } = crypto.generateKeyPairSync(
'ec',
{
namedCurve: NAMED_CURVE,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
},
}
);
console.log(`publicKey:\n${publicKey}`);
//////////////////////////////////////////////////
// SIGN
//////////////////////////////////////////////////
const headerBase64Url = toBase64Url(header);
const payloadBase64Url = toBase64Url(payload);
const data = `${headerBase64Url}.${payloadBase64Url}`;
const signature = crypto.sign(ALGORITHM, data, privateKey);
const signatureBase64Url = toBase64Url(signature);
const jsonWebToken = `${data}.${signatureBase64Url}`;
console.log('Token:', jsonWebToken, '\n');
//////////////////////////////////////////////////
// VERIFY
//////////////////////////////////////////////////
const jwtParts = jsonWebToken.split('.');
const jwtHeaderBase64Url = jwtParts[0];
const jwtPayloadBase64Url = jwtParts[1];
const jwtSignatureBase64Url = jwtParts[2];
const jwtHeaderObject = fromBase64Url(jwtHeaderBase64Url, true);
const jwtPayloadObject = fromBase64Url(jwtPayloadBase64Url, true);
const jwtSignatureBuffer = fromBase64Url(jwtSignatureBase64Url);
if (jwtHeaderObject.alg !== header.alg)
throw new Error('Invalid algorithm');
const jwtData = `${jwtHeaderBase64Url}.${jwtPayloadBase64Url}`;
const isValid = crypto.verify(ALGORITHM, jwtData, publicKey, jwtSignatureBuffer);
console.log('Verify:', isValid); // true
console.log('Header:', jwtHeaderObject); // { alg: 'ES256', typ: 'JWT' }
console.log('Payload:', jwtPayloadObject); // { data: 'Hello World!' }Node.js v24.7.0.
import crypto from 'node:crypto';
// Base 64 Encoding with URL and Filename Safe Alphabet.
function toBase64Url(data) {
if (Buffer.isBuffer(data))
return data.toString('base64url');
if (typeof(data) !== 'string')
data = JSON.stringify(data);
return toBase64Url(Buffer.from(data));
}
function fromBase64Url(data, parseJson) {
data = Buffer.from(data, 'base64url');
if (parseJson != null)
data = data.toString('utf8');
return parseJson ? JSON.parse(data) : data;
}
//////////////////////////////////////////////////
// JWT: HEADER & PAYLOAD
//////////////////////////////////////////////////
// Post-Quantum Cryptography (NIST FIPS 204, ML-DSA)
// Module-Lattice-Based Digital Signature Algorithm (MLDSA)
const ALG = 'MLDSA44'; // 'MLDSA44' | 'MLDSA65' | 'MLDSA87'
const KEY_TYPE = 'ml-dsa-44'; // 'ml-dsa-44' | 'ml-dsa-65' | 'ml-dsa-87'
const header = { alg: ALG, typ: 'JWT' };
const payload = { data: 'Hello World!' };
//////////////////////////////////////////////////
// KEYS
//////////////////////////////////////////////////
const { publicKey, privateKey } = crypto.generateKeyPairSync(
KEY_TYPE,
{
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
},
}
);
console.log(`publicKey:\n${publicKey}`);
//////////////////////////////////////////////////
// SIGN
//////////////////////////////////////////////////
const headerBase64Url = toBase64Url(header);
const payloadBase64Url = toBase64Url(payload);
const data = `${headerBase64Url}.${payloadBase64Url}`;
const signature = crypto.sign(null, data, privateKey);
const signatureBase64Url = toBase64Url(signature);
const jsonWebToken = `${data}.${signatureBase64Url}`;
console.log(`Token:\n${jsonWebToken}\n`);
//////////////////////////////////////////////////
// VERIFY
//////////////////////////////////////////////////
const jwtParts = jsonWebToken.split('.');
const jwtHeaderBase64Url = jwtParts[0];
const jwtPayloadBase64Url = jwtParts[1];
const jwtSignatureBase64Url = jwtParts[2];
const jwtHeaderObject = fromBase64Url(jwtHeaderBase64Url, true);
const jwtPayloadObject = fromBase64Url(jwtPayloadBase64Url, true);
const jwtSignatureBuffer = fromBase64Url(jwtSignatureBase64Url);
if (jwtHeaderObject.alg !== header.alg)
throw new Error('Invalid algorithm');
const jwtData = `${jwtHeaderBase64Url}.${jwtPayloadBase64Url}`;
const isValid = crypto.verify(null, jwtData, publicKey, jwtSignatureBuffer);
console.log('Verify:', isValid); // true
console.log('Header:', jwtHeaderObject); // { alg: 'MLDSA44', typ: 'JWT' }
console.log('Payload:', jwtPayloadObject); // { data: 'Hello World!' }