UNPKG

exceljs

Version:

Excel Workbook Manager - Read and Write xlsx and csv Files.

56 lines (52 loc) 2 kB
'use strict'; const crypto = require('crypto'); const Encryptor = { /** * Calculate a hash of the concatenated buffers with the given algorithm. * @param {string} algorithm - The hash algorithm. * @returns {Buffer} The hash */ hash(algorithm, ...buffers) { const hash = crypto.createHash(algorithm); hash.update(Buffer.concat(buffers)); return hash.digest(); }, /** * Convert a password into an encryption key * @param {string} password - The password * @param {string} hashAlgorithm - The hash algoritm * @param {string} saltValue - The salt value * @param {number} spinCount - The spin count * @param {number} keyBits - The length of the key in bits * @param {Buffer} blockKey - The block key * @returns {Buffer} The encryption key */ convertPasswordToHash(password, hashAlgorithm, saltValue, spinCount) { hashAlgorithm = hashAlgorithm.toLowerCase(); const hashes = crypto.getHashes(); if (hashes.indexOf(hashAlgorithm) < 0) { throw new Error(`Hash algorithm '${hashAlgorithm}' not supported!`); } // Password must be in unicode buffer const passwordBuffer = Buffer.from(password, 'utf16le'); // Generate the initial hash let key = this.hash(hashAlgorithm, Buffer.from(saltValue, 'base64'), passwordBuffer); // Now regenerate until spin count for (let i = 0; i < spinCount; i++) { const iterator = Buffer.alloc(4); // this is the 'special' element of Excel password hashing // that stops us from using crypto.pbkdf2() iterator.writeUInt32LE(i, 0); key = this.hash(hashAlgorithm, key, iterator); } return key.toString('base64'); }, /** * Generates cryptographically strong pseudo-random data. * @param size The size argument is a number indicating the number of bytes to generate. */ randomBytes(size) { return crypto.randomBytes(size); }, }; module.exports = Encryptor;