首页指南参考教程

EAS 更新代码签名

了解 EAS 更新中代码签名和密钥轮换的工作原理。


EAS 更新代码签名仅适用于订阅 EAS Enterprise 计划的账户。报名

介绍

¥Introduction

expo-updates 库支持端到端代码签名。代码签名允许开发者使用自己的密钥对更新进行加密签名。然后在应用更新之前在客户端上验证签名,这确保 ISP、CDN、云提供商甚至 EAS 本身无法篡改应用运行的更新。

¥The expo-updates library supports end-to-end code signing. Code signing allows developers to cryptographically sign their updates with their own keys. The signatures are then verified on the client before the update is applied, which ensures ISPs, CDNs, cloud providers, and even EAS itself cannot tamper with updates run by apps.

使用 EAS 更新进行代码签名

¥Code signing with EAS Update

1

为你的应用生成私钥和相应的代码签名证书:

¥Generate a private key and corresponding code signing certificate for your app:

Terminal
npx expo-updates codesigning:generate \
--key-output-directory keys \ --certificate-output-directory certs \ --certificate-validity-duration-years 10 \ --certificate-common-name "My App"
  • 生成的私钥必须保密且安全。

    ¥The generated private key must be kept private and secure.

  • 证书有效期的设置可能会根据应用的安全需求而有所不同。

    ¥The certificate validity duration is a setting that may vary based on the security needs of your app.

    • 较短的有效期将更频繁地需要 密钥轮换,但被认为是更好的做法,因为受损的私钥将更快到期,从而限制暴露。

      ¥A shorter validity duration will require key rotation more frequently but is considered better practice since a compromised private key will have a sooner expiration which limits exposure.

    • 较短的有效期会增加应用发布过程的开销,因为密钥必须更频繁地轮换。证书过期的二进制文件将不会应用新的更新。

      ¥Shorter validity durations add overhead to your app's release process as the key must be rotated more frequently. Binaries with expired certificates won't apply new updates.

    • 例如,对于公共 Expo Go 应用,Expo 将此值设置为 20 年,但对于具有更频繁分发的二进制文件的内部应用,仅为 1 年。我们计划每 10 年轮换一次密钥。

      ¥For example, Expo sets this value to 20 years for the public Expo Go app, but only 1 year for internal apps with binaries that are distributed more frequently. We plan to rotate our keys every 10 years.

2

配置应用的构建以使用代码签名:

¥Configure your app's builds to use code signing:

Terminal
npx expo-updates codesigning:configure --certificate-input-directory certs --key-input-directory keys

完成此步骤后,使用新的运行时版本创建新版本。代码签名证书将嵌入到这个新版本中。

¥After this step, create a new build with a new runtime version. The code signing certificate will be embedded in this new build.

3

为你的应用发布签名更新:

¥Publish a signed update for your app:

Terminal
eas update --private-key-path keys/private-key.pem

eas update 期间,EAS CLI 自动检测是否为你的应用配置了代码签名。然后,它会验证更新的完整性并使用你的私钥创建数字签名。此过程在本地执行,因此你的私钥永远不会离开你的计算机。生成的签名会自动发送到 EAS 并与更新一起存储。

¥During eas update, the EAS CLI automatically detects that code signing is configured for your app. It then verifies the integrity of the update and creates a digital signature using your private key. This process is performed locally so that your private key never leaves your machine. The generated signature is automatically sent to EAS to store alongside the update.

4

在客户端上下载更新(此步骤由库自动补齐)。配置用于代码签名的步骤 (2) 中的构建会检查是否有可用的新更新。服务器以步骤 (3) 中发布的更新及其生成的签名进行响应。下载后但在应用之前,将根据嵌入的证书和包含的签名来验证更新。如果证书和签名有效,则应用更新,否则拒绝。

¥Download the update on the client (this step is done automatically by the library). The build from step (2) that is configured for code signing checks if there is a new update available. The server responds with the update published in step (3) and its generated signature. After being downloaded but before being applied, the update is verified against the embedded certificate and included signature. The update is applied if the certificate and signature are valid, and rejected otherwise.

密钥轮换

¥Key rotation

密钥轮换是更改用于签名更新的密钥对的过程。这在以下几种情况下最常见:

¥Key rotation is the process by which the key pair used for signing updates is changed. This is most commonly done in a few cases:

  • 密钥过期。在上一节的步骤 (1) 中,我们将 certificate-validity-duration-years 设置为 10 年(尽管它可以配置为任何值)。这意味着 10 年后,使用证书对应的私钥签名的更新在被应用下载后将不再应用。在签名证书到期之前下载的更新将继续正常运行。在证书过期之前轮换密钥有助于预防任何潜在的密钥过期问题,并有助于保证所有用户在旧证书过期之前使用新证书。

    ¥Key expiration. In step (1) from the section above, we set certificate-validity-duration-years to 10 years (though it can be configured to any value). This means that after 10 years, updates signed with the private key corresponding to the certificate will no longer be applied after being downloaded by the app. Updates downloaded before the expiration of their signing certificate will continue to function normally. Rotating keys well before the certificate expires helps to preempt any potential key expiration issues and helps to guarantee all users are using the new certificate before the old certificate expires.

  • 私钥泄露。如果用于签署更新的私钥意外地暴露给公众,则它不再被认为是安全的,因此无法再保证其签名的更新的完整性。例如,恶意行为者可以制作恶意更新并使用泄露的私钥对其进行签名。

    ¥Private key compromise. If the private key used to sign updates is accidentally exposed to the public, it can no longer be considered secure and therefore can no longer guarantee integrity of updates it signed. For example, a malicious actor could craft a malicious update and sign it with the leaked private key.

  • 安全最佳实践的密钥轮换。最佳实践是定期轮换密钥,以确保系统能够适应上述其他原因之一的手动密钥轮换。

    ¥Key rotation for security best practices. It is best practice to rotate keys periodically to ensure that a system is resilient to manual key rotation in response to one of the other reasons above.

在任何这些情况下,程序都是相似的:

¥In any of these cases, the procedure is similar:

  1. 备份在上述步骤 (1) 中生成的旧密钥和证书。

    ¥Backup the old key and certificate that were generated in step (1) above.

  2. 按照上述步骤生成新密钥。为了帮助调试,你可能希望通过修改应用配置 (app.json) 中的 updates.codeSigningMetadata.keyid 字段来更改新密钥的 keyid

    ¥Generate a new key by following the steps above. To assist in debugging, you may wish to change the keyid of the new key by modifying the updates.codeSigningMetadata.keyid field in your app config (app.json).

  3. 该证书是应用运行时的一部分,因此应为使用此证书的构建设置新的运行时版本,以确保只有使用新密钥签名的更新才能在新构建中运行。

    ¥The certificate is part of the app's runtime, so a new runtime version should be set for builds using this certificate to ensure that only updates signed with the new key run in the new build.

  4. 按照上述步骤 (3) 使用新密钥发布签名更新。

    ¥Publish signed updates using the new key by following step (3) above.

删除代码签名

¥Removing code signing

从应用中删除代码签名的过程与 密钥轮换 类似,可以视为 null 密钥的密钥轮换。

¥The process of removing code signing from an app is similar to key rotation and can be thought of as a key rotation to a null key.

  1. 备份在上述步骤 (1) 中生成的旧密钥和证书。

    ¥Backup the old key and certificate that were generated in step (1) above.

  2. 从应用配置 (app.json) 中删除 updates.codeSigningMetadata 字段。

    ¥Remove the updates.codeSigningMetadata field from your app config (app.json).

  3. 新的无证书应用是一个新的独特运行时,因此应为构建设置新的运行时版本,以确保在新构建中仅运行未签名的更新。

    ¥The new certificate-less app is a new distinct runtime, so a new runtime version should be set for builds to ensure that only unsigned updates run in the new build.

Expo 中文网 - 粤ICP备13048890号