Nodejs crypto.getHashes () возвращает пустой массив - PullRequest
3 голосов
/ 27 января 2020

Я использовал excel js 'Защита листа , когда обнаружил ошибку - Error: Hash algorithm 'sha512' not supported!. Изучив исходные файлы, я обнаружил причину ошибки: crypto.getHashes() возвращает пустой массив. Кажется, я не могу найти решение или причину для пустого массива, какие-либо идеи?

Узел v11.2.0

Excel JS v3.6.0

src / router / export-excel / customer.ts

import ExcelJS from "exceljs";

const workbook = new ExcelJS.Workbook();

// workbook config

workbook.eachSheet(async (worksheet, sheetId) => {
  worksheet.eachRow((row, rowNumber) => {
    row.eachCell((cell, colNumber) => {
      switch (exportCols.getCodes()[colNumber - 1]) {
         // other case statements
         case "date_created":
         case "date_modified":
           cell.protection = { locked: false }; // locks the cells under the date created & modified columns
           break;
      }
    })
    await worksheet.protect("passWord123", {
        selectLockedCells: false,
        formatCells: true,
        insertRows: true,
        // other config props 
      });
  })
})

excel js lib - определение метода защиты

node_modules/exceljs/lib/utils/worksheet.js Worksheet.protect

// Worksheet Protection
  protect(password, options) {
    // TODO: make this function truly async
    // perhaps marshal to worker thread or something
    return new Promise(resolve => {
      this.sheetProtection = {
        sheet: true,
      };
      if (password) {
        this.sheetProtection.algorithmName = 'SHA-512';
        this.sheetProtection.saltValue = Encryptor.randomBytes(16).toString('base64');
        this.sheetProtection.spinCount = 100000;
        this.sheetProtection.hashValue = Encryptor.convertPasswordToHash(password, 'SHA512', this.sheetProtection.saltValue, this.sheetProtection.spinCount);
      }
      if (options) {
        this.sheetProtection = Object.assign(this.sheetProtection, options);
      }
      resolve();
    });
  }

excel js lib - определение метода convertPasswordToHa sh

node_modules/exceljs/lib/utils/encryptor.js Encryptor.convertPasswordToHash

convertPasswordToHash(password, hashAlgorithm, saltValue, spinCount) {
    hashAlgorithm = hashAlgorithm.toLowerCase();
    const hashes = crypto.getHashes();
    console.log("supported hashes", hashes) // <== hashes was empty w/c caused the 'Hash algorithm '${hashAlgorithm}' not supported!' error to be thrown
    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');
  }

Если кто-либо Нужно больше разъяснений, пожалуйста, не стесняйтесь оставлять комментарии внизу.

Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 28 января 2020

В несвязанном проекте есть ошибка , из-за которой crypto.getHashes может вернуть пустой массив, если прототип массива был изменен. В отчете об ошибке это было связано с использованием наборов. js.

Изменение прототипа массива с помощью собственного кода или стороннего модуля, импортированного до Модуль crypto, может заставить crypto.getHashes возвращать пустой массив.

...