简体   繁体   English

Nodejs crypto.getHashes() 返回一个空数组

[英]Nodejs crypto.getHashes() returns an empty array

I was using exceljs' sheet protection feature when I encountered an error– Error: Hash algorithm 'sha512' not supported!当我遇到Error: Hash algorithm 'sha512' not supported!时,我正在使用exceljs的工作表保护功能– Error: Hash algorithm 'sha512' not supported! . . After taking a look into it's source files I discovered the cause of the error: crypto.getHashes() is returning an empty array.在查看它的源文件后,我发现了错误的原因: crypto.getHashes()正在返回一个空数组。 I can't seem to find a solution nor the reason for the empty array, any ideas?我似乎找不到解决方案,也找不到空数组的原因,有什么想法吗?

Node v11.2.0节点 v11.2.0

ExcelJS v3.6.0 ExcelJS v3.6.0

src/routes/export-excel/customer.ts src/routes/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 
      });
  })
})

exceljs lib - defenition of the protect method exceljs 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();
    });
  }

exceljs lib - defenition of the convertPasswordToHash method exceljs lib - convertPasswordToHash 方法的定义

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');
  }

If anyone needs more clarification please don't hesitate to leave a comment down below.如果有人需要更多说明,请随时在下面发表评论。

Any help would be much appreciated.任何帮助将非常感激。

There is a bug on an unrelated project that suggests crypto.getHashes can return an empty array if the array prototype has been modified.一个不相关的项目有一个bug,它表明如果数组原型被修改, crypto.getHashes可以返回一个空数组。 In the bug report, it was due to the use of collections.js .在错误报告中,这是由于使用了collections.js

Modifying the array prototype, either by your own code or by a third-party module imported before the crypto module, can cause crypto.getHashes to return an empty array.通过您自己的代码或在crypto模块之前导入的第三方模块修改数组原型,可能会导致crypto.getHashes返回一个空数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM