* 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
(password, hashAlgorithm, saltValue, spinCount)
| 24 | * @returns {Buffer} The encryption key |
| 25 | */ |
| 26 | convertPasswordToHash(password, hashAlgorithm, saltValue, spinCount) { |
| 27 | hashAlgorithm = hashAlgorithm.toLowerCase(); |
| 28 | const hashes = crypto.getHashes(); |
| 29 | if (hashes.indexOf(hashAlgorithm) < 0) { |
| 30 | throw new Error(`Hash algorithm '${hashAlgorithm}' not supported!`); |
| 31 | } |
| 32 | |
| 33 | // Password must be in unicode buffer |
| 34 | const passwordBuffer = Buffer.from(password, 'utf16le'); |
| 35 | // Generate the initial hash |
| 36 | let key = this.hash(hashAlgorithm, Buffer.from(saltValue, 'base64'), passwordBuffer); |
| 37 | // Now regenerate until spin count |
| 38 | for (let i = 0; i < spinCount; i++) { |
| 39 | const iterator = Buffer.alloc(4); |
| 40 | // this is the 'special' element of Excel password hashing |
| 41 | // that stops us from using crypto.pbkdf2() |
| 42 | iterator.writeUInt32LE(i, 0); |
| 43 | key = this.hash(hashAlgorithm, key, iterator); |
| 44 | } |
| 45 | return key.toString('base64'); |
| 46 | }, |
| 47 | /** |
| 48 | * Generates cryptographically strong pseudo-random data. |
| 49 | * @param size The size argument is a number indicating the number of bytes to generate. |
nothing calls this directly
no test coverage detected
searching dependent graphs…