在构建过程中运行适用于 Windows / NSIS 的电子构建器后,我们的开发运营团队设置了一个构建脚本,该脚本运行以在部署之前对 exe 进行代码签名。到达服务器后,Electron-Updater 因 sha512 校验和不匹配而失败(完全下载后在安装过程中发生错误)。我还尝试从服务器上拉下 exe 文件并从 Visual Studio CMD 运行 codesign util,然后重新上传。自动更新程序也失败并出现相同的错误。
是否无法在生成 exe 后对其进行签名,并且仍然允许自动更新程序工作?
签名:
signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /sha1 value "path"
日志:
Error: sha512 checksum mismatch, expected [value], got [different value]
package.json中的配置:
"build": {
"appId": "com.stripped.stripped.stripped",
"directories": {
"output": "dist-exe",
"app": "dist"
},
"win": {
"target": "nsis",
"icon": "dist/assets/favicon/favicon-256x256.ico",
"verifyUpdateCodeSignature": false,
"publish": {
"provider": "generic",
"url": "##{ElecronAppUpdaterLocation}##"
}
},
"nsis": {
"artifactName": "Setup_${version}.${ext}",
"installerIcon": "dist/assets/favicon/favicon-256x256.ico",
"installerHeaderIcon": "dist/assets/favicon/favicon-256x256.ico"
}
}
https://github.com/electron-userland/electron-builder/issues/3913#issuecomment-504698845
我已经测试过它,它工作正常,Electron 能够将应用程序更新到具有手动生成的校验和的版本。
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const YOUR_FILE_PATH = ''; // POPULATE THIS
function hashFile(file, algorithm = 'sha512', encoding = 'base64', options) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash(algorithm);
hash.on('error', reject).setEncoding(encoding);
fs.createReadStream(
file,
Object.assign({}, options, {
highWaterMark: 1024 * 1024,
/* better to use more memory but hash faster */
})
)
.on('error', reject)
.on('end', () => {
hash.end();
console.log('hash done');
console.log(hash.read());
resolve(hash.read());
})
.pipe(
hash,
{
end: false,
}
);
});
}
const installerPath = path.resolve(
__dirname,
YOUR_FILE_PATH
);
hashFile(installerPath);
当我这样做时,自动更新效果很好,希望它有帮助>
<
对 GH 中电子构建器问题的响应,生成后不允许进行签名,不幸的是,这改变了我们的构建流程。
我的设置是,我正在 Linux 上构建 Windows NSIS 目标,并且我想使用存储在 USB 记忆棒上的 EV 代码签名证书对其进行签名。我还没有力量尝试让它在 Linux 上工作,所以目前我的脚本将暂停 electro-bulder 进程,直到我使用在同一机器上运行的 Windows VM 完成手动签名 .exe(基本但它有效)。
我的 package.json 的相关部分是
"build": {
...
"win": {
...
"sign": "scripts/sign.js",
"signingHashAlgorithms": ["sha256"], # sign.js will be called once for each hash algorithm
...
},
"nsis": {
...
}
}
我的sign.js 文件看起来像
const readline = require("node:readline")
const { stdin: input, stdout: output } = require("node:process")
const INSTALLER_PREFIX = ... // Set expected installer prefix here
// A very low tech placeholder to last until we can work out how to sign using the
// Sectigo EV USB on the linux command line
exports.default = async function (configuration) {
if (configuration.path.startsWith(INSTALLER_PREFIX)) {
const rl = readline.createInterface({ input, output })
await new Promise(function(resolve) {
rl.question("Please sign the exe and press enter when complete... ", () => {
rl.close()
resolve()
})
});
}
}
这个脚本可以使用新的 Node JS Promise API 进行一些简化,但它在我当前使用的 NodeJS 版本中不可用。一旦签名完成,电子构建器将继续计算签名的 exe 的 sha512 校验和,并且所有这些都可以与自动更新程序配合使用。