Electron 桌面应用签名与公证
🎯 引言
打包只是生成应用文件,签名是让操作系统知道“这个应用由谁发布,并且文件没有被发布后修改”。macOS 还需要公证,公证可以理解为把应用交给 Apple 检查后,获得系统认可。
本篇会分别走一遍 macOS 和 Windows 的签名流程。你不需要同时发布两个系统,先选择自己手上的系统练习即可。
先明确三件事:
- 没有证书时,Forge 不能凭空完成正式签名。
- 证书和密码不能写进代码仓库。
- 本地学习可以先不签名,正式分发时再完成签名和平台检查。
🧱 签名流程总览
无论哪个系统,基本流程都类似:
申请并安装证书
↓
在 Forge 配置签名信息
↓
生成安装包
↓
验证签名
↓
在干净系统中安装测试
macOS 比 Windows 多一步公证:
macOS 签名 → 上传 Apple 公证 → 下载公证结果 → 验证
🍎 macOS:签名和公证
第一步:在哪里申请 Apple 证书
正式分发到用户电脑时,需要加入 Apple Developer Program,再到 Apple Developer 账号的 Certificates, Identifiers & Profiles → Certificates 页面申请证书。
操作路径是:
- 登录 Apple Developer 账号。
- 打开 Certificates, Identifiers & Profiles → Certificates。
- 点击右上角的加号。
- 选择 Developer ID Application。
- 按页面要求创建证书签名请求文件(
.certSigningRequest)。 - 上传请求文件,下载生成的
.cer文件。 - 双击
.cer,把证书安装到 macOS 的“钥匙串访问”。
Developer ID Application 是给 Mac 应用签名的证书,不要选成只用于 Mac App Store 的证书。Apple 的证书申请页面见:Developer ID certificates。
证书安装到当前 Mac 后,先用命令检查:
security find-identity -p codesigning -v
如果列表中能看到 Developer ID Application,说明当前 Mac 已经有可用于应用签名的证书。
第二步:让 Forge 使用证书
在 forge.config.js 的 packagerConfig 中加入 osxSign: {}:
module.exports = {
packagerConfig: {
icon: './assets/icon',
osxSign: {},
},
};
osxSign: {} 的意思是让 Forge 使用当前 Mac 已安装的签名证书。它不是创建证书,只是告诉 Forge“打包时执行 macOS 签名”。
执行打包:
npm run package
第三步:验证签名
把下面路径换成 out 目录中实际生成的 .app 路径:
codesign --verify --deep --strict --verbose=2 \
'out/electron-course-darwin-arm64/Electron Course.app'
没有报错,说明代码签名校验通过。签名校验通过不代表已经完成公证,公证还要继续执行。
第四步:在哪里提交 macOS 公证
公证不是在 Electron Forge 页面里完成的,而是把已经签名的应用提交给 Apple 的 Notary Service 检查。Forge 会替你调用 Apple 的服务,但你仍然要准备认证信息。
常见认证方式有两种,初学时选择一种即可:
- Apple ID + 应用专用密码 + Team ID。
- App Store Connect API Key。
如果使用 API Key,登录 App Store Connect,进入 Users and Access → Integrations → App Store Connect API → Team Keys,创建并下载 API Key。私钥只允许下载一次,要安全保存。具体入口见 Apple 官方说明。
下面使用 Apple ID 和应用专用密码:
module.exports = {
packagerConfig: {
osxSign: {},
osxNotarize: {
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD,
teamId: process.env.APPLE_TEAM_ID,
},
},
};
在当前终端提供这些环境变量,再执行:
export APPLE_ID='你的 Apple 账号'
export APPLE_APP_SPECIFIC_PASSWORD='应用专用密码'
export APPLE_TEAM_ID='你的 Team ID'
npm run make
其中:
APPLE_ID:你的 Apple 账号邮箱。APPLE_APP_SPECIFIC_PASSWORD:Apple 账号生成的应用专用密码,不是登录密码。APPLE_TEAM_ID:Apple Developer 账号中的 Team ID。
Forge 会在打包过程中完成签名并提交公证。公证完成后,可以检查应用是否被系统认可:
spctl --assess --type execute --verbose \
'out/electron-course-darwin-arm64/Electron Course.app'
macOS 需要记住什么
osxSign负责签名。osxNotarize负责提交 Apple 公证。- 签名证书和公证凭证是两件不同的东西。
- 签名通过不等于公证通过。
🪟 Windows:签名安装程序
第一步:在哪里申请 Windows 证书
Windows 证书不是从 Electron Forge 申请的,而是向代码签名证书服务商申请。申请时选择 Windows Code Signing Certificate,审核通过后通常会获得 .pfx 证书文件和证书密码。
也可以使用 Microsoft 的云端签名服务,但它有地区、账号和组织资格限制。初学时先记住:你需要先从证书服务商或 Microsoft 签名服务获得一个可用的 Windows 签名身份。
Electron Forge 的 Windows 签名说明见:Signing a Windows app。
证书一般以 .pfx 文件提供,同时会有证书密码。
把 .pfx 文件放在项目之外,或者放在不会提交到 Git 的安全目录中。不要把证书复制到 assets,也不要把密码写进 forge.config.js。
第二步:配置 Forge
在 Windows 的 Squirrel maker 中填写证书路径和密码:
module.exports = {
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {
certificateFile: process.env.WINDOWS_CERTIFICATE_FILE,
certificatePassword: process.env.WINDOWS_CERTIFICATE_PASSWORD,
},
},
],
};
这里使用环境变量,是为了避免密码出现在代码和 Git 历史中。
第三步:生成签名安装包
Windows PowerShell 中执行:
$env:WINDOWS_CERTIFICATE_FILE = 'C:\certs\electron-course.pfx'
$env:WINDOWS_CERTIFICATE_PASSWORD = '证书密码'
npm run make
Forge 会在生成 Squirrel.Windows 安装程序时使用这份证书。安装程序生成后,再用 Windows 的签名工具验证签名:
signtool verify /pa .\out\make\squirrel.windows\x64\*.exe
实际路径和文件名以 out 目录中的产物为准。
🔐 发布前的安全检查
发布签名前,至少检查下面几项:
[ ] 证书文件没有提交到 Git
[ ] 证书密码没有写进源码
[ ] macOS 已通过 codesign 验证
[ ] macOS 对外发布时已完成公证
[ ] Windows 安装程序已通过 signtool 验证
[ ] 在没有开发工具的干净系统中安装并启动
[ ] 签名后的应用仍然能正常更新和卸载
如果使用 CI/CD,证书和密码应该配置为 CI 的加密 Secret,构建脚本只读取环境变量。
🧾 小节总结
- 签名需要真实的平台证书,Forge 只负责使用证书完成打包签名。
- macOS 需要
osxSign,对外发布通常还需要osxNotarize。 - Windows 使用
.pfx和密码配置 Squirrel maker。 - 签名完成后要使用系统工具验证,不能只看 Forge 是否执行成功。
- 证书和密码必须放在安全环境中,不能提交到 Git。
❓ 知识问答
Q1:没有证书能不能学习 Electron?
A:可以。学习阶段先执行 npm run package 和 npm run make,签名可以等到正式分发时再做。
Q2:macOS 签名和公证是一回事吗?
A:不是。签名证明应用来源,公证是 Apple 对应用进行检查并记录结果。
Q3:为什么不能把 .pfx 放进项目?
A:.pfx 通常包含私钥,泄露后别人可能冒用你的发布身份。
Q4:Forge 打包成功,是否代表签名一定成功?
A:不一定。必须使用 codesign 或 signtool 验证最终产物。
🧪 小练习
练习一:在自己的开发机上执行证书查询命令,确认系统是否存在可用签名证书。
练习二:检查 .gitignore 是否包含本地证书文件、环境变量文件和签名日志。
🎉 现在你已经掌握了 Electron 签名流程中“证书、Forge 配置、构建和验证”的完整关系。
