【发布时间】:2020-01-27 05:42:34
【问题描述】:
我在使用exceljs' sheet protection 功能时遇到错误–Error: Hash algorithm 'sha512' not supported!。在查看了它的源文件后,我发现了错误的原因:crypto.getHashes() 正在返回一个空数组。我似乎找不到解决方案,也找不到空数组的原因,有什么想法吗?
节点 v11.2.0
ExcelJSv3.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');
}
如果有人需要更多说明,请随时在下方发表评论。
任何帮助将不胜感激。
【问题讨论】:
-
请提供更多信息,例如您编写的代码。
标签: javascript node.js typescript exceljs