Mac App Store 提交指南
本指南提供了有关以下方面的信息
- 如何在 macOS 上签名 Electron 应用;
- 如何将 Electron 应用提交到 Mac App Store (MAS);
- MAS 构建的限制。
要求
要签名 Electron 应用,首先必须安装以下工具
- Xcode 11 或更高版本。
- The @electron/osx-sign npm 模块。
您还必须注册一个 Apple 开发者帐户并加入 Apple Developer Program。
签名 Electron 应用
Electron 应用可以通过 Mac App Store 或其外部分发。每种方式都需要不同的签名和测试方法。本指南重点介绍通过 Mac App Store 进行分发。
以下步骤描述了如何从 Apple 获取证书,如何签名 Electron 应用以及如何测试它们。
获取证书
获取签名证书最简单的方法是使用 Xcode
- 打开 Xcode 并打开“帐户”首选项;
- 使用您的 Apple 帐户登录;
- 选择一个团队,然后单击“管理证书”;
- 在签名证书工作表的左下角,单击“添加”按钮 (+) 并添加以下证书
- "Apple 开发"
- "Apple 分发"
"Apple 开发"证书用于在已在 Apple Developer 网站上注册的机器上对开发和测试应用进行签名。注册方法将在 准备配置文件 中进行描述。
使用“Apple 开发”证书签名的应用无法提交到 Mac App Store。为此,应用必须改为使用“Apple 分发”证书进行签名。但请注意,使用“Apple 分发”证书签名的应用无法直接运行,它们必须由 Apple 重新签名才能运行,这只有在从 Mac App Store 下载后才能实现。
其他证书
您可能会注意到还有其他类型的证书。
"开发者 ID 应用程序"证书用于在将应用分发到 Mac App Store 之外之前对应用进行签名。
"开发者 ID 安装程序"和"Mac 安装程序分发"证书用于对 Mac 安装程序包而不是应用本身进行签名。大多数 Electron 应用不使用 Mac 安装程序包,因此通常不需要它们。
证书类型的完整列表可以在 此处 找到。
使用“Apple 开发”和“Apple 分发”证书签名的应用只能在 App Sandbox 下运行,因此它们必须使用 Electron 的 MAS 构建版本。但是,“开发者 ID 应用程序”证书没有此限制,因此使用它签名的应用可以使用 Electron 的普通构建版本或 MAS 构建版本。
旧版证书名称
Apple 在过去几年中一直在更改证书的名称,您在阅读旧文档时可能会遇到它们,并且某些实用程序仍在使用旧名称之一。
- "Apple 分发"证书也称为"第三方 Mac 开发者应用程序"和"Mac 应用分发"。
- "Apple 开发"证书也称为"Mac 开发者"和"开发"。
准备配置文件
如果要在将应用提交到 Mac App Store 之前在本地机器上测试应用,则必须使用嵌入在应用包中的配置文件,使用“Apple 开发”证书对应用进行签名。
要 创建配置文件,您可以按照以下步骤操作
- 在 Apple Developer 网站上打开“证书、标识符和配置文件”页面。
- 在“标识符”页面中为您的应用添加新的 App ID。
- 在“设备”页面中注册您的本地机器。您可以在“系统信息”应用的“硬件”页面中找到机器的“设备 ID”。
- 在“配置文件”页面中注册一个新的配置文件,并将其下载到
/path/to/yourapp.provisionprofile
。
启用 Apple 的 App Sandbox
提交到 Mac App Store 的应用必须在 Apple 的 App Sandbox 下运行,并且只有 Electron 的 MAS 构建版本才能与 App Sandbox 一起运行。Electron 的标准 darwin 构建版本在 App Sandbox 下运行时将无法启动。
使用 @electron/osx-sign
对应用进行签名时,它会自动将必要的权利添加到应用的权利文件中。
不使用 electron-osx-sign
的额外步骤
如果您未使用 @electron/osx-sign
对应用进行签名,则必须确保应用包的权利文件中至少包含以下键
<?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.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>TEAM_ID.your.bundle.id</string>
</array>
</dict>
</plist>
TEAM_ID
应替换为您的 Apple 开发者帐户的团队 ID,your.bundle.id
应替换为应用的 App ID。
并且以下权利必须添加到应用包中的二进制文件和帮助程序中
<?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.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
并且应用包的 Info.plist
必须包含 ElectronTeamID
键,其值为您的 Apple 开发者帐户的团队 ID
<plist version="1.0">
<dict>
...
<key>ElectronTeamID</key>
<string>TEAM_ID</string>
</dict>
</plist>
使用 @electron/osx-sign
时,ElectronTeamID
键将通过从证书名称中提取团队 ID 自动添加。如果 @electron/osx-sign
无法找到正确的团队 ID,则可能需要手动添加此键。
为开发签名应用
要对可在开发机器上运行的应用进行签名,必须使用“Apple 开发”证书对其进行签名,并将配置文件传递给 @electron/osx-sign
。
const { signAsync } = require('@electron/osx-sign')
signAsync({
app: '/path/to/your.app',
identity: 'Apple Development',
provisioningProfile: '/path/to/your.provisionprofile'
})
如果您未使用 @electron/osx-sign
进行签名,则必须将配置文件放置到 YourApp.app/Contents/embedded.provisionprofile
。
签名的应用只能在配置文件注册的机器上运行,这是在提交到 Mac App Store 之前测试签名的应用的唯一方法。
为提交到 Mac App Store 签名应用
要对将提交到 Mac App Store 的应用进行签名,必须使用“Apple 分发”证书对其进行签名。请注意,使用此证书签名的应用将无法在任何地方运行,除非它是从 Mac App Store 下载的。
const { signAsync } = require('@electron/osx-sign')
signAsync({
app: 'path/to/your.app',
identity: 'Apple Distribution'
})
将应用提交到 Mac App Store
使用“Apple 分发”证书对应用签名后,您可以继续将其提交到 Mac App Store。
但是,本指南不能保证您的应用会被 Apple 批准;您仍然需要阅读 Apple 的 提交您的应用 指南,了解如何满足 Mac App Store 要求。
上传
Apple Transporter 应用于将签名的应用上传到 App Store Connect 以进行处理,确保您已 创建了记录 然后再上传。
如果您看到类似于使用了私有 API 的错误,则应检查应用是否使用了 Electron 的 MAS 构建版本。
提交审查
上传后,您应该 提交您的应用以供审查。
MAS 构建的限制
为了满足应用沙盒的所有要求,MAS 构建版本中已禁用以下模块
crashReporter
自动更新器
以及以下行为已更改
- 某些机器上的视频捕获可能无法正常工作。
- 某些辅助功能可能无法正常工作。
- 应用程序将无法感知 DNS 更改。
此外,由于使用了应用程序沙盒,应用程序可以访问的资源受到严格限制;您可以阅读应用程序沙盒以获取更多信息。
其他授权
每个在应用程序沙盒下运行的应用程序都将在有限的权限集下运行,从而限制恶意代码造成的潜在损害。根据您的应用程序使用的 Electron API,您可能需要向应用程序的授权文件中添加其他授权。否则,应用程序沙盒可能会阻止您使用它们。
授权使用类似属性列表 (.plist
) 或 XML 格式的文件指定。您必须为应用程序包本身提供授权文件,并提供一个子授权文件,该文件基本上描述了所有其他封闭可执行文件(如二进制文件、框架 (.framework
) 和动态链接库 (.dylib
))指定的属性的继承。
完整的授权列表可在应用程序沙盒文档中找到,但以下是一些 MAS 应用程序可能需要的授权。
使用 @electron/osx-sign
,您可以为每个文件设置自定义授权,如下所示
const { signAsync } = require('@electron/osx-sign')
function getEntitlementsForFile (filePath) {
if (filePath.startsWith('my-path-1')) {
return './my-path-1.plist'
} else {
return './alternate.plist'
}
}
signAsync({
optionsForFile: (filePath) => ({
// Ensure you return the right entitlements path here based on the file being signed.
entitlements: getEntitlementsForFile(filePath)
})
})
网络访问
启用传出网络连接以允许您的应用程序连接到服务器
<key>com.apple.security.network.client</key>
<true/>
启用传入网络连接以允许您的应用程序打开网络侦听套接字
<key>com.apple.security.network.server</key>
<true/>
有关更多详细信息,请参阅启用网络访问文档。
dialog.showOpenDialog
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
有关更多详细信息,请参阅启用用户选择的文件访问文档。
dialog.showSaveDialog
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
有关更多详细信息,请参阅启用用户选择的文件访问文档。
Electron 使用的加密算法
根据您发布应用程序的国家/地区,您可能需要提供有关软件中使用的加密算法的信息。有关更多信息,请参阅加密出口合规性文档。
Electron 使用以下加密算法
- AES - NIST SP 800-38A,NIST SP 800-38D,RFC 3394
- HMAC - FIPS 198-1
- ECDSA - ANS X9.62–2005
- ECDH - ANS X9.63–2001
- HKDF - NIST SP 800-56C
- PBKDF2 - RFC 2898
- RSA - RFC 3447
- SHA - FIPS 180-4
- Blowfish - https://www.schneier.com/cryptography/blowfish/
- CAST - RFC 2144,RFC 2612
- DES - FIPS 46-3
- DH - RFC 2631
- DSA - ANSI X9.30
- EC - SEC 1
- IDEA - X. Lai 编著的“关于分组密码的设计和安全性”一书
- MD2 - RFC 1319
- MD4 - RFC 6150
- MD5 - RFC 1321
- MDC2 - ISO/IEC 10118-2
- RC2 - RFC 2268
- RC4 - RFC 4345
- RC5 - https://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf
- RIPEMD - ISO/IEC 10118-3