UNPKG

react-native-quick-crypto

Version:

A fast implementation of Node's `crypto` module written in C/C++ JSI

89 lines (87 loc) 3.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pbkdf2 = pbkdf2; exports.pbkdf2DeriveBits = pbkdf2DeriveBits; exports.pbkdf2Sync = pbkdf2Sync; var _reactNativeBuffer = require("@craftzdog/react-native-buffer"); var _reactNativeNitroModules = require("react-native-nitro-modules"); var _utils = require("./utils"); var _util = require("util"); const WRONG_PASS = 'Password must be a string, a Buffer, a typed array or a DataView'; const WRONG_SALT = `Salt must be a string, a Buffer, a typed array or a DataView`; // to use native bits in sub-functions, use getNative(). don't call it at top-level! let native; function getNative() { if (native == null) { // lazy-load the Nitro HybridObject native = _reactNativeNitroModules.NitroModules.createHybridObject('Pbkdf2'); } return native; } function sanitizeInput(input, errorMsg) { try { return (0, _utils.binaryLikeToArrayBuffer)(input); // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (_e) { throw new Error(errorMsg); } } function pbkdf2(password, salt, iterations, keylen, digest, callback) { if (callback === undefined || typeof callback !== 'function') { throw new Error('No callback provided to pbkdf2'); } const sanitizedPassword = sanitizeInput(password, WRONG_PASS); const sanitizedSalt = sanitizeInput(salt, WRONG_SALT); const normalizedDigest = (0, _utils.normalizeHashName)(digest, _utils.HashContext.Node); getNative(); native.pbkdf2(sanitizedPassword, sanitizedSalt, iterations, keylen, normalizedDigest).then(res => { callback(null, _reactNativeBuffer.Buffer.from(res)); }, e => { callback(e); }); } function pbkdf2Sync(password, salt, iterations, keylen, digest) { const sanitizedPassword = sanitizeInput(password, WRONG_PASS); const sanitizedSalt = sanitizeInput(salt, WRONG_SALT); const algo = digest ? (0, _utils.normalizeHashName)(digest, _utils.HashContext.Node) : 'sha1'; getNative(); const result = native.pbkdf2Sync(sanitizedPassword, sanitizedSalt, iterations, keylen, algo); return _reactNativeBuffer.Buffer.from(result); } // We need this because the typescript overload signatures in pbkdf2() above do // not play nice with promisify() below. const pbkdf2WithDigest = (password, salt, iterations, keylen, digest, callback) => pbkdf2(password, salt, iterations, keylen, digest, callback); const pbkdf2Promise = (0, _util.promisify)(pbkdf2WithDigest); async function pbkdf2DeriveBits(algorithm, baseKey, length) { const { iterations, hash, salt } = algorithm; const normalizedHash = (0, _utils.normalizeHashName)(hash); if (!normalizedHash) { throw (0, _utils.lazyDOMException)('hash cannot be blank', 'OperationError'); } if (!iterations || iterations === 0) { throw (0, _utils.lazyDOMException)('iterations cannot be zero', 'OperationError'); } if (!salt) { throw (0, _utils.lazyDOMException)(WRONG_SALT, 'OperationError'); } const raw = baseKey.keyObject.export(); if (length === 0) throw (0, _utils.lazyDOMException)('length cannot be zero', 'OperationError'); if (length === null) throw (0, _utils.lazyDOMException)('length cannot be null', 'OperationError'); if (length % 8) { throw (0, _utils.lazyDOMException)('length must be a multiple of 8', 'OperationError'); } const sanitizedPassword = sanitizeInput(raw, WRONG_PASS); const sanitizedSalt = sanitizeInput(salt, WRONG_SALT); const result = await pbkdf2Promise(sanitizedPassword, sanitizedSalt, iterations, length / 8, normalizedHash); if (!result) { throw (0, _utils.lazyDOMException)('received bad result from pbkdf2()', 'OperationError'); } return (0, _utils.bufferLikeToArrayBuffer)(result); } //# sourceMappingURL=pbkdf2.js.map