MacOS下Electron Node.js应用公证(签名)失败:错误码66求助
Electron Forge 公证失败:Staple错误代码66(CDHash必须设置)排查方案
问题背景
按照Electron Forge官方指南的「应用专用密码」选项,为Electron Node.js应用完成公证(Code Sign)并提交Mac App Store时,执行npm run make反复报错:
Failed to staple your application with code: 66. Cannot download ticket. CDHash must be set.
现有配置文件
forge.config.js
module.exports = { packagerConfig: { osxSign: {}, osxNotarize: { tool: 'notarytool', appleId: '******', appleIdPassword: '******', teamId: '******', } }, rebuildConfig: {}, makers: [ { name: '@electron-forge/maker-squirrel', config: {}, }, { name: '@electron-forge/maker-zip', platforms: ['darwin'], }, { name: '@electron-forge/maker-deb', config: {}, }, { name: '@electron-forge/maker-rpm', config: {}, }, ], };
package.json 脚本配置
"scripts": { "start": "electron-forge start", "package": "electron-forge package", "make": "electron-forge make" },
完整错误日志
An unhandled rejection has occurred inside Forge: Error: Failed to staple your application with code: 66 Processing: /private/var/folders/h3/vkfpv17950z45hg1z5tjfq000000gn/T/electron-packager/darwin-x64/myapp-darwin-x64-wgLqgW/myapp.app Properties are { NSURLIsDirectoryKey = 1; NSURLIsPackageKey = 1; NSURLIsSymbolicLinkKey = 0; NSURLLocalizedTypeDescriptionKey = Application; NSURLTypeIdentifierKey = "com.apple.application-bundle"; "_NSURLIsApplicationKey" = 1; } Props are { } Cannot download ticket. CDHash must be set. at Object.<anonymous> (/path/myapp/node_modules/@electron/notarize/lib/staple.js:22:19) at Generator.next (<anonymous>) at fulfilled (/path/myapp/node_modules/@electron/notarize/lib/staple.js:4:58) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
排查与解决步骤
1. 补全签名配置(核心问题)
当前osxSign为空对象,缺少公证必需的签名参数,导致应用未正确签名、无法生成CDHash。修改forge.config.js中的osxSign配置:
osxSign: { // 替换为你的开发者ID应用签名证书名称,可通过`security find-identity -v -p codesigning`查看 identity: "Developer ID Application: Your Full Name (YOUR_TEAM_ID)", // 启用 hardened runtime(公证强制要求) hardenedRuntime: true, // 指定权限文件路径 entitlements: "./entitlements.plist", entitlementsInherit: "./entitlements.plist", // 跳过Gatekeeper检测(打包阶段不需要) gatekeeperAssess: false, // 深度签名应用内所有组件 flags: ["--deep", "--force"] }
同时在项目根目录创建entitlements.plist文件,添加Electron应用必需的权限:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> <key>com.apple.security.cs.debugger</key> <true/> </dict> </plist>
2. 验证签名有效性
执行npm run package完成打包后,手动检查应用签名状态:
codesign -dv --verbose=4 ./out/myapp-darwin-x64/myapp.app
查看输出是否包含CDHash字段,若存在则签名正常;若不存在,检查证书是否正确安装、配置的identity名称是否匹配。
3. 确认公证配置正确性
appleId:确保是开发者账号的Apple IDappleIdPassword:必须是应用专用密码(在Apple ID管理页面生成,需开启双重认证)teamId:可在Apple开发者后台的「会员中心」查看
4. 分步执行打包流程
避免一次性执行npm run make,分步操作排查问题:
npm run package:完成打包与签名- 手动执行公证(可选,用于验证):
npx electron-notarize notarize --tool notarytool --appleId YOUR_APPLE_ID --appleIdPassword YOUR_APP_SPECIFIC_PASSWORD --teamId YOUR_TEAM_ID --app ./out/myapp-darwin-x64/myapp.app
- 手动执行staple:
xcrun stapler staple ./out/myapp-darwin-x64/myapp.app
5. 清理临时缓存
删除Electron Forge生成的临时打包目录(错误日志中/private/var/folders/.../myapp.app路径),避免缓存的未签名文件干扰重新打包。
内容的提问来源于stack exchange,提问作者Bhavitej Rayalacheruvu
相关产品推荐
相关产品推荐

