@syncfusion/ej2-pdf
Version:
Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.
266 lines (265 loc) • 11.8 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { _areArrayEqual } from '../../utils';
import { _AdvancedEncryption128Cipher, _AdvancedEncryption256Cipher } from './advance-cipher';
import { _Sha256 } from './secureHash-algorithm256';
import { _Sha512 } from './secureHash-algorithm512';
/**
* Abstract base for encryption key helpers used internally by PDF encryption.
*
* @private
*/
var _EncryptionKey = /** @class */ (function () {
function _EncryptionKey() {
}
Object.defineProperty(_EncryptionKey.prototype, "_sha256", {
/**
* Lazily-created SHA-256 instance.
*
* @private
* @returns {_Sha256} The `_Sha256` instance.
*/
get: function () {
if (typeof this._sha256Obj === 'undefined' || this._sha256Obj === null) {
this._sha256Obj = new _Sha256();
}
return this._sha256Obj;
},
enumerable: true,
configurable: true
});
Object.defineProperty(_EncryptionKey.prototype, "_sha512", {
/**
* Lazily-created SHA-512 instance.
*
* @private
* @returns {_Sha512} The `_Sha512` instance.
*/
get: function () {
if (typeof this._sha512Obj === 'undefined' || this._sha512Obj === null) {
this._sha512Obj = new _Sha512();
}
return this._sha512Obj;
},
enumerable: true,
configurable: true
});
return _EncryptionKey;
}());
export { _EncryptionKey };
// PDF17 encryption support
/**
* Basic (PDF 1.7) encryption helper implementing `_EncryptionKey`.
*
* @private
*/
var _BasicEncryption = /** @class */ (function (_super) {
__extends(_BasicEncryption, _super);
function _BasicEncryption() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Validate the owner password for PDF 1.7-style encryption.
*
* @private
* @param {Uint8Array} password - The candidate password.
* @param {Uint8Array} ownerValidationSalt - Salt for owner validation.
* @param {Uint8Array} userBytes - Additional user bytes used in hashing.
* @param {Uint8Array} ownerPassword - Expected owner password hash.
* @returns {boolean} `true` when the owner password is valid.
*/
_BasicEncryption.prototype._checkOwnerPassword = function (password, ownerValidationSalt, userBytes, ownerPassword) {
var hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0);
hashData.set(ownerValidationSalt, password.length);
hashData.set(userBytes, password.length + ownerValidationSalt.length);
var result = this._sha256._hash(hashData, 0, hashData.length);
return _areArrayEqual(result, ownerPassword);
};
/**
* Validate the user password for PDF 1.7-style encryption.
*
* @private
* @param {Uint8Array} password - The candidate password.
* @param {Uint8Array} userValidationSalt - Salt for user validation.
* @param {Uint8Array} userPassword - Expected user password hash.
* @returns {boolean} `true` when the user password is valid.
*/
_BasicEncryption.prototype._checkUserPassword = function (password, userValidationSalt, userPassword) {
var hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0);
hashData.set(userValidationSalt, password.length);
var result = this._sha256._hash(hashData, 0, hashData.length);
return _areArrayEqual(result, userPassword);
};
/**
* Derive the owner key for PDF 1.7-style encryption.
*
* @private
* @param {Uint8Array} password - The password to derive from.
* @param {Uint8Array} ownerKeySalt - Salt used for owner key derivation.
* @param {Uint8Array} userBytes - Additional user bytes used in derivation.
* @param {Uint8Array} ownerEncryption - Encrypted owner data to decrypt.
* @returns {Uint8Array} The derived owner key bytes.
*/
_BasicEncryption.prototype._getOwnerKey = function (password, ownerKeySalt, userBytes, ownerEncryption) {
var hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0);
hashData.set(ownerKeySalt, password.length);
hashData.set(userBytes, password.length + ownerKeySalt.length);
var key = this._sha256._hash(hashData, 0, hashData.length);
return (new _AdvancedEncryption256Cipher(key))._decryptBlock(ownerEncryption, false, new Uint8Array(16));
};
/**
* Derive the user key for PDF 1.7-style encryption.
*
* @private
* @param {Uint8Array} password - The password to derive from.
* @param {Uint8Array} userKeySalt - Salt used for user key derivation.
* @param {Uint8Array} userEncryption - Encrypted user data to decrypt.
* @returns {Uint8Array} The derived user key bytes.
*/
_BasicEncryption.prototype._getUserKey = function (password, userKeySalt, userEncryption) {
var hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0);
hashData.set(userKeySalt, password.length);
var key = this._sha256._hash(hashData, 0, hashData.length);
return (new _AdvancedEncryption256Cipher(key))._decryptBlock(userEncryption, false, new Uint8Array(16));
};
return _BasicEncryption;
}(_EncryptionKey));
export { _BasicEncryption };
// PDF20 encryption support
/**
* Advanced (PDF 2.0) encryption helper implementing `_EncryptionKey`.
*
* @private
*/
var _AdvancedEncryption = /** @class */ (function (_super) {
__extends(_AdvancedEncryption, _super);
function _AdvancedEncryption() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Validate the owner password for PDF 2.0-style encryption.
*
* @private
* @param {Uint8Array} password - The candidate password.
* @param {Uint8Array} ownerValidationSalt - Salt for owner validation.
* @param {Uint8Array} userBytes - Additional user bytes used in hashing.
* @param {Uint8Array} ownerPassword - Expected owner password hash.
* @returns {boolean} `true` when the owner password is valid.
*/
_AdvancedEncryption.prototype._checkOwnerPassword = function (password, ownerValidationSalt, userBytes, ownerPassword) {
var hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0);
hashData.set(ownerValidationSalt, password.length);
hashData.set(userBytes, password.length + ownerValidationSalt.length);
var result = this._hash(password, hashData, userBytes);
return _areArrayEqual(result, ownerPassword);
};
_AdvancedEncryption.prototype._checkUserPassword = function (password, userValidationSalt, userPassword) {
var hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0);
hashData.set(userValidationSalt, password.length);
var result = this._hash(password, hashData, new Uint8Array([]));
return _areArrayEqual(result, userPassword);
};
/**
* Derive the owner key for PDF 2.0-style encryption.
*
* @private
* @param {Uint8Array} password - The password to derive from.
* @param {Uint8Array} ownerKeySalt - Salt used for owner key derivation.
* @param {Uint8Array} userBytes - Additional user bytes used in derivation.
* @param {Uint8Array} ownerEncryption - Encrypted owner data to decrypt.
* @returns {Uint8Array} The derived owner key bytes.
*/
_AdvancedEncryption.prototype._getOwnerKey = function (password, ownerKeySalt, userBytes, ownerEncryption) {
var hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0);
hashData.set(ownerKeySalt, password.length);
hashData.set(userBytes, password.length + ownerKeySalt.length);
var key = this._hash(password, hashData, userBytes);
return (new _AdvancedEncryption256Cipher(key))._decryptBlock(ownerEncryption, false, new Uint8Array(16));
};
/**
* Derive the user key for PDF 2.0-style encryption.
*
* @private
* @param {Uint8Array} password - The password to derive from.
* @param {Uint8Array} userKeySalt - Salt used for user key derivation.
* @param {Uint8Array} userEncryption - Encrypted user data to decrypt.
* @returns {Uint8Array} The derived user key bytes.
*/
_AdvancedEncryption.prototype._getUserKey = function (password, userKeySalt, userEncryption) {
var hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0);
hashData.set(userKeySalt, password.length);
var key = this._hash(password, hashData, new Uint8Array([]));
var cipher = new _AdvancedEncryption256Cipher(key);
return cipher._decryptBlock(userEncryption, false, new Uint8Array(16));
};
/**
* Internal iterative hash routine used by PDF 2.0 encryption key derivation.
*
* @private
* @param {Uint8Array} password - The password bytes.
* @param {Uint8Array} input - Input data for the hash routine.
* @param {Uint8Array} userBytes - User-specific bytes influencing the result.
* @returns {Uint8Array} A 32-byte hash used as an intermediate key.
*/
_AdvancedEncryption.prototype._hash = function (password, input, userBytes) {
var data = this._sha256._hash(input, 0, input.length).subarray(0, 32);
var encrypted = new Uint8Array([0]);
var i = 0;
while (i < 64 || encrypted[encrypted.length - 1] > i - 32) {
var combinedLength = password.length + data.length + userBytes.length;
var combinedArray = new Uint8Array(combinedLength);
var writeOffset = 0;
combinedArray.set(password, writeOffset);
writeOffset += password.length;
combinedArray.set(data, writeOffset);
writeOffset += data.length;
combinedArray.set(userBytes, writeOffset);
var k1 = new Uint8Array(combinedLength * 64);
for (var j = 0, pos = 0; j < 64; j++) {
k1.set(combinedArray, pos);
pos += combinedLength;
}
var cipher = new _AdvancedEncryption128Cipher(data.subarray(0, 16));
encrypted = cipher._encrypt(k1, data.subarray(16, 32));
var remainder = 0;
for (var z = 0; z < 16; z++) {
remainder *= 256 % 3;
remainder %= 3;
remainder += (encrypted[z] >>> 0) % 3;
remainder %= 3;
}
if (remainder === 2) {
data = this._sha512._hash(encrypted, 0, encrypted.length);
}
else if (remainder === 1) {
data = this._sha512._hash(encrypted, 0, encrypted.length, true);
}
else if (remainder === 0) {
data = this._sha256._hash(encrypted, 0, encrypted.length);
}
i++;
}
return data.subarray(0, 32);
};
return _AdvancedEncryption;
}(_EncryptionKey));
export { _AdvancedEncryption };