繁体   English   中英

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

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

当我遇到Error: Hash algorithm 'sha512' not supported!时,我正在使用exceljs的工作表保护功能– Error: Hash algorithm 'sha512' not supported! . 在查看它的源文件后,我发现了错误的原因: crypto.getHashes()正在返回一个空数组。 我似乎找不到解决方案,也找不到空数组的原因,有什么想法吗?

节点 v11.2.0

ExcelJS v3.6.0

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 -保护方法的定义

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

如果有人需要更多说明,请随时在下面发表评论。

任何帮助将非常感激。

一个不相关的项目有一个bug,它表明如果数组原型被修改, crypto.getHashes可以返回一个空数组。 在错误报告中,这是由于使用了collections.js

通过您自己的代码或在crypto模块之前导入的第三方模块修改数组原型,可能会导致crypto.getHashes返回一个空数组。

暂无
暂无

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

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