跳转到内容

如何在 Info.plist 中填写 App Encryption Information

当你上传 TestFlight build 或提交版本给 App Review 时,App Store Connect 会询问应用是否使用加密。如果答案不会随 build 改变,可以直接在应用的 Info.plist 中声明加密信息。这样就不必每次上传都重复填写 export compliance 问卷。

通常需要的 key 是 ITSAppUsesNonExemptEncryption。这个名称很容易误读:它问的不是应用是否使用任何加密,而是应用是否使用 non-exempt encryption,也就是不属于豁免范围的加密。

大多数应用可以按下面的方式判断:

  • 如果应用不使用加密,或只使用豁免的加密,将 ITSAppUsesNonExemptEncryption 设为 NO / false
  • 如果应用使用 non-exempt encryption,将 ITSAppUsesNonExemptEncryption 设为 YES / true
  • 只有在 Apple 批准 export compliance 文档并提供代码后,才添加 ITSEncryptionExportComplianceCode
  • 如果省略 ITSAppUsesNonExemptEncryption,App Store Connect 可能会在每次上传新 build 时询问加密问题。

常见的 false 场景包括:应用只通过 Apple 网络 API 使用 HTTPS,使用 Keychain、CryptoKit、Security framework、CloudKit、StoreKit、Sign in with Apple,或其他仅限 Apple 操作系统提供的加密能力。如果应用集成了会自行实现加密的第三方 SDK,请单独确认。

在 Xcode 中打开应用 target:

  1. 在 navigator 中选择项目。
  2. 选择应用 target。
  3. 打开 Info 标签。
  4. 添加新的 custom property,名称为 App Uses Non-Exempt Encryption
  5. 将类型设为 Boolean
  6. 将值设为 NOYES

Xcode 会把它写成 Info.plist 的原始 key:ITSAppUsesNonExemptEncryption

对于这个 Boolean key,NO 表示 falseYES 表示 true

如果应用不使用 non-exempt encryption,请在 Xcode 中设为 NO。raw plist 中应写成:

<key>ITSAppUsesNonExemptEncryption</key>
<false/>

如果应用使用 non-exempt encryption,请在 Xcode 中设为 YES。raw plist 中应写成:

<key>ITSAppUsesNonExemptEncryption</key>
<true/>

请确认值是真正的 Boolean,而不是字符串 "NO""YES""FALSE""TRUE"

当应用不使用加密,或只使用 Apple 认为不需要提交 export compliance documentation 的豁免加密时,在 Xcode 中使用 NO,在 raw plist 中使用 false

典型场景:

  • 应用通过 HTTPS 连接你的 backend;
  • 加密仅限 iOS、iPadOS、macOS、watchOS、tvOS 或 visionOS 提供的 API;
  • 应用把凭据存储在 Keychain;
  • 应用使用 Apple frameworks 处理登录、购买、iCloud、CloudKit 或 push notifications;
  • 第三方 SDK 没有额外加入自己的 non-exempt encryption。

这也是普通 consumer app 最常见的情况:应用通过 TLS 调用 API,但没有实现自己的 security layer。

当应用使用 non-exempt encryption 时,在 Xcode 中使用 YES,在 raw plist 中使用 true。这可能包括应用包含或链接了不限于 Apple 操作系统的加密能力,使用 proprietary 或 unpublished cryptography,或根据 App Store Connect 问卷结果需要提交 export compliance documentation。

需要额外检查的例子:

  • VPN、安全消息、password manager、加密存储、安全或 antivirus 应用;
  • proprietary 或 non-standard encryption algorithms;
  • 内置 crypto libraries,例如 OpenSSL、libsodium 或自定义 cryptography module;
  • 在 Apple 操作系统之外自行实现的 industry-standard algorithms;
  • 加密是产品核心能力的功能。

如果 App Store Connect 判断需要文档,请在提交 TestFlight review 或 App Review 前上传所需文档。

如果需要提交文档,App Store Connect 可能会在 export compliance documentation 获批后提供一个代码。将这个值填入 ITSEncryptionExportComplianceCode

<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>ITSEncryptionExportComplianceCode</key>
<string>YOUR_APPROVED_CODE</string>

不要自己编造这个值。它必须是 Apple 审核你的文档后提供的代码。

不确定时先用 App Store Connect 判断

Section titled “不确定时先用 App Store Connect 判断”

如果不确定应用的加密状态,先回答 Apple 的问卷:

  1. 打开 App Store Connect
  2. 选择应用。
  3. 打开 App Information
  4. 找到 App Encryption Documentation
  5. 点击添加按钮并回答问题。

你也可以在 TestFlight 或 Distribution 页面,点击缺少加密信息的 build 旁边的 Manage

当 App Store Connect 确认不需要文档后,将 ITSAppUsesNonExemptEncryption 设为 NO / false。如果需要文档,先上传文档,等待 Apple 审核,必要时将已批准的文档关联到 build,然后把 compliance code 添加到 Info.plist

这个值必须出现在最终上传应用包里的 plist 中。如果 App Store Connect 仍然反复询问同样的加密问题,请检查:

  • key 添加到了错误的 target;
  • Release configuration 使用了另一个 Info.plist
  • build script 在 archive 过程中生成或覆盖了 plist;
  • key 被添加成 string,而不是 Boolean;
  • plist 修改前就已经上传了 build;
  • ITSAppUsesNonExemptEncryptionYES / true,但必需文档还没有获批或关联。

对于 React Native、Flutter、Unity 和其他 cross-platform 项目,请编辑 iOS app target 最终使用的 Info.plist,而不只是框架层的配置文件。

很多应用只通过 HTTPS 调用 backend,并使用 Apple frameworks 处理本地存储、购买、通知和登录。对于这种情况,通常使用:

<key>ITSAppUsesNonExemptEncryption</key>
<false/>

上传包含这个 key 的新 build 后,只要应用的加密行为没有变化,App Store Connect 就不应再要求你每次提交都填写 export compliance 问卷。