UNPKG

@syncfusion/ej2-pdf

Version:

Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.

199 lines (198 loc) 7.81 kB
import { _bytesToBigInt, _bigIntToBytes, _modPow, _createRandomInRange, _modInverse, _getBigInt } from '../../../utils'; /** * Provides the internal RSA core operations, including modular exponentiation, * CRT optimization for private keys, and block size management. * * @private */ var _PdfRsaCoreAlgorithm = /** @class */ (function () { function _PdfRsaCoreAlgorithm() { } /** * Gets the maximum input block size in bytes based on the key size and operation mode. * * @private * @returns {number} The allowed input block size in bytes. */ _PdfRsaCoreAlgorithm.prototype._getInputBlockSize = function () { return this._isEncryption ? (this._bitSize - 1) >>> 3 : (this._bitSize + 7) >>> 3; }; /** * Gets the maximum output block size in bytes based on the key size and operation mode. * * @private * @returns {number} The output block size in bytes. */ _PdfRsaCoreAlgorithm.prototype._getOutputBlockSize = function () { return this._isEncryption ? (this._bitSize + 7) >>> 3 : (this._bitSize - 1) >>> 3; }; /** * Initializes the RSA core engine with the specified mode and key parameters. * * @private * @param {boolean} isEncryption Specifies whether to operate in encryption mode. * @param {_PdfCipherParameter} parameters The RSA key parameters to use. * @returns {void} nothing. */ _PdfRsaCoreAlgorithm.prototype._initialize = function (isEncryption, parameters) { this._key = parameters; this._isEncryption = isEncryption; this._bitSize = this._key.modulus._bitLength(); }; /** * Converts a segment of bytes into a bigint suitable for RSA modular operations, * validating the block size and modulus constraints. * * @private * @param {Uint8Array} bytes The source byte array. * @param {number} offset The starting index within the array. * @param {number} length The number of bytes to read. * @returns {bigint} The bigint representation of the input block. */ _PdfRsaCoreAlgorithm.prototype._convertInput = function (bytes, offset, length) { var subBytes = bytes.subarray(offset, offset + length); if (subBytes.length > this._getInputBlockSize() + 1) { throw new Error('Input data too large for RSA block.'); } var input = _bytesToBigInt(subBytes); if (input >= this._key.modulus) { throw new Error('Input data is larger than modulus.'); } return input; }; /** * Converts a bigint result back into a byte array, padding as required for encryption output size. * * @private * @param {bigint} result The bigint value to convert. * @returns {Uint8Array} The converted byte array. */ _PdfRsaCoreAlgorithm.prototype._convertOutput = function (result) { var output = _bigIntToBytes(result); if (this._isEncryption) { var outSize = this._getOutputBlockSize(); if (output.length < outSize) { var paddedOutput = new Uint8Array(outSize); paddedOutput.set(output, outSize - output.length); return paddedOutput; } } return output; }; /** * Processes a single RSA block using modular exponentiation. If a CRT private key is present, * uses the CRT optimization; otherwise, falls back to standard exponentiation. * * @private * @param {bigint} input The bigint block to process. * @returns {bigint} The processed bigint result. */ _PdfRsaCoreAlgorithm.prototype._processBlock = function (input) { var bigInt = _getBigInt(); var privateKey = this._key; // eslint-disable-line if (privateKey._isPrivate && privateKey.p && privateKey.q) { var p = privateKey.p._toBigInt(); var q = privateKey.q._toBigInt(); var dP = privateKey.dP._toBigInt(); var dQ = privateKey.dQ._toBigInt(); var qInv = privateKey.inverse._toBigInt(); var mP = _modPow(input % p, dP, p); var mQ = _modPow(input % q, dQ, q); var h = (mP - mQ) * qInv; h = h % p; if (h < bigInt('0')) { h += p; } var m = h * q; m = m + mQ; return m; } return _modPow(input, this._key.exponent, this._key.modulus); }; return _PdfRsaCoreAlgorithm; }()); export { _PdfRsaCoreAlgorithm }; /** * Provides the internal RSA block cipher wrapper built on top of the RSA core, * exposing block size and processing methods for encryption/decryption. * * @private */ var _PdfRsaAlgorithm = /** @class */ (function () { function _PdfRsaAlgorithm() { this._rsaCoreEngine = new _PdfRsaCoreAlgorithm(); } /** * Gets the internal algorithm name. * * @private * @returns {string} The algorithm name, i.e., "RSA". */ _PdfRsaAlgorithm.prototype._getAlgorithmName = function () { return 'RSA'; }; /** * Gets the maximum input block size in bytes for the current key and mode. * * @private * @returns {number} The input block size in bytes. */ _PdfRsaAlgorithm.prototype._getInputBlock = function () { return this._rsaCoreEngine._getInputBlockSize(); }; /** * Gets the maximum output block size in bytes for the current key and mode. * * @private * @returns {number} The output block size in bytes. */ _PdfRsaAlgorithm.prototype._getOutputBlock = function () { return this._rsaCoreEngine._getOutputBlockSize(); }; /** * Initializes the RSA algorithm with the specified mode and parameters. * * @private * @param {boolean} isEncryption Specifies whether to operate in encryption mode. * @param {_PdfCipherParameter} parameter The RSA key parameters to use. * @returns {void} nothing. */ _PdfRsaAlgorithm.prototype._initialize = function (isEncryption, parameter) { this._rsaCoreEngine._initialize(isEncryption, parameter); this._key = parameter; }; /** * Processes a single block of input using RSA. Applies blinding when a private key is used * and a public exponent is available to mitigate timing attacks. * * @private * @param {Uint8Array} bytes The input buffer containing the block data. * @param {number} offset The starting index of the block within the buffer. * @param {number} length The number of bytes to process from the buffer. * @returns {Uint8Array} The processed output block. */ _PdfRsaAlgorithm.prototype._processBlock = function (bytes, offset, length) { var bigInt = _getBigInt(); if (!this._key) { throw new Error('RSA engine not initialized.'); } var input = this._rsaCoreEngine._convertInput(bytes, offset, length); var result; var privateKey = this._key; // eslint-disable-line if (privateKey._isPrivate && privateKey.publicExponent) { var e = privateKey.publicExponent._toBigInt(); var m = this._key.modulus._toBigInt(); var r = _createRandomInRange(bigInt(1), m - bigInt(1)); var blindedInput = (_modPow(r, e, m) * input) % m; var blindedResult = this._rsaCoreEngine._processBlock(blindedInput); var rInverse = _modInverse(r, m); result = (blindedResult * rInverse) % m; } else { result = this._rsaCoreEngine._processBlock(input); } return this._rsaCoreEngine._convertOutput(result); }; return _PdfRsaAlgorithm; }()); export { _PdfRsaAlgorithm };