/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
lib/internal/crypto/pbkdf2.js
133 строки
3 KB
Jordan Harband
crypto: coerce -0 keylen to +0 in pbkdf2 and scrypt
26 май 2026, 12:25
26 май 2026, 12:25
3393399
Код
Авторство
О чём код?
'use strict'; const { ArrayBuffer, FunctionPrototypeCall, PromiseResolve, } = primordials; const { Buffer } = require('buffer'); const { PBKDF2Job, kCryptoJobAsync, kCryptoJobSync, kCryptoJobWebCrypto, } = internalBinding('crypto'); const { validateFunction, validateInt32, validateString, } = require('internal/validators'); const { getArrayBufferOrView, normalizeHashName, jobPromise, } = require('internal/crypto/util'); const { lazyDOMException, } = require('internal/util'); const { getCryptoKeyHandle, } = require('internal/crypto/keys'); function pbkdf2(password, salt, iterations, keylen, digest, callback) { if (typeof digest === 'function') { callback = digest; digest = undefined; } ({ password, salt, iterations, keylen, digest } = check(password, salt, iterations, keylen, digest)); validateFunction(callback, 'callback'); const job = new PBKDF2Job( kCryptoJobAsync, password, salt, iterations, keylen, digest); job.ondone = (err, result) => { if (err !== undefined) return FunctionPrototypeCall(callback, job, err); const buf = Buffer.from(result); return FunctionPrototypeCall(callback, job, null, buf); }; job.run(); } function pbkdf2Sync(password, salt, iterations, keylen, digest) { ({ password, salt, iterations, keylen, digest } = check(password, salt, iterations, keylen, digest)); const job = new PBKDF2Job( kCryptoJobSync, password, salt, iterations, keylen, digest); const { 0: err, 1: result } = job.run(); if (err !== undefined) throw err; return Buffer.from(result); } function check(password, salt, iterations, keylen, digest) { validateString(digest, 'digest'); password = getArrayBufferOrView(password, 'password'); salt = getArrayBufferOrView(salt, 'salt'); // OpenSSL uses a signed int to represent these values, so we are restricted // to the 31-bit range here (which is plenty). validateInt32(iterations, 'iterations', 1); validateInt32(keylen, 'keylen', 0); // Coerce -0 to +0. keylen += 0; return { password, salt, iterations, keylen, digest }; } function validatePbkdf2DeriveBitsLength(length) { if (length === null) throw lazyDOMException('length cannot be null', 'OperationError'); if (length % 8) { throw lazyDOMException( 'length must be a multiple of 8', 'OperationError'); } } function pbkdf2DeriveBits(algorithm, baseKey, length) { validatePbkdf2DeriveBitsLength(length); const { iterations, hash, salt } = algorithm; if (length === 0) return PromiseResolve(new ArrayBuffer(0)); return jobPromise(() => new PBKDF2Job( kCryptoJobWebCrypto, getCryptoKeyHandle(baseKey), salt, iterations, length / 8, normalizeHashName(hash.name))); } module.exports = { pbkdf2, pbkdf2Sync, pbkdf2DeriveBits, validatePbkdf2DeriveBitsLength, };