签署您的应用--手动签署 APK

时间:2024-03-21 19:37:50

签署您的应用

Android 要求所有 APK 必须先使用证书进行数字签署,然后才能安装。本文档介绍了如何使用 Android Studio 签署您的 APK,包括创建和存储证书、使用不同证书签署不同的构建配置,以及配置构建流程以自动签署您的 APK。

证书和密钥库


公钥证书(也称为数字证书或身份证书)包含公钥/私钥对的公钥,以及可以标识密钥所有者的一些其他元数据(例如名称和位置)。证书的所有者持有对应的私钥。

在您签署 APK 时,签署工具会将公钥证书附加到 APK。公钥证书充当“指纹”,用于将 APK 唯一关联到您及您的对应私钥。这有助于 Android 确保您 APK 的任何将来更新都是原版更新并来自原始作者。用于创建此证书的密钥称为应用签名密钥

密钥库是一种包含一个或多个私钥的二进制文件。

每个应用在其整个生命周期内必须使用相同证书,以便用户能够以应用更新的形式安装新版本。要详细了解为所有应用在其整个生命周期内使用相同证书的好处,请参阅下面的签署注意事项

签署您的调试构建


从 IDE 中运行或调试您的项目时,Android Studio 将自动使用通过 Android SDK 工具生成的调试证书签署您的 APK。当您在 Android Studio 中首次运行或调试项目时,IDE 将自动在 $HOME/.android/debug.keystore中创建调试密钥库和证书,并设置密钥库和密钥密码。

由于调试证书通过构建工具创建并且在设计上不安全,大多数应用商店(包括 Google Play 商店)都不接受使用调试证书签署要发布的 APK。

Android Studio 会自动将您的调试签署信息存储在签署配置中,因此您不必在每次调试时都输入此信息。签署配置是一种包含签署 APK 所需全部必要信息的对象,这些信息包括密钥库位置、密钥库密码、密钥名称和密钥密码。您无法直接编辑调试签署配置,不过可以配置如何签署您的发布构建

如需了解有关如何针对调试构建和运行应用的详细信息,请参阅构建和运行您的应用

调试证书的有效期

用于针对调试签署 APK 的自签署证书的有效期为 365 天,从其创建日期算起。当此证书到期时,您将收到一个构建错误。

若要修复此问题,删除 debug.keystore 文件即可。文件存储在以下位置:

  • ~/.android/(OS X 和 Linux)
  • C:\Documents and Settings\<user>\.android\(Windows XP)
  • C:\Users\<user>\.android\ (Windows Vista,Windows 7、8 和 10)

当您下次构建和运行调试构建类型时,这些构建工具将重新生成新的密钥库和调试密钥。请注意,您必须运行应用,单纯的构建不会重新生成密钥库和调试密钥。

管理您的密钥


由于您的应用签名密钥用于验证您作为开发者的身份,并确保为您的用户进行无缝而安全的更新,因此,管理和保护您的密钥对于您和您的用户而言都非常重要。您可以选择使用 Google Play 应用签名以利用 Google 的基础架构安全地管理和存储您的应用签名密钥,也可以选择自行管理和保护您的密钥库和应用签名密钥。

使用 Google Play 应用签名

使用 Google Play 应用签名时,您将使用两个密钥:应用签名密钥上传密钥。Google 为您管理和保护应用签名密钥,您保留上传密钥并使用它签署您的应用,以便上传到 Google Play 商店。

当您选择使用 Google Play 应用签名时,您应使用 Google Play 提供的 Play Encrypt Private Key 工具导出和加密您的应用签名密钥,然后将它上传到 Google 的基础架构。然后,您创建一个单独的上传密钥并向 Google 注册该密钥。当您准备发布应用时,使用上传密钥签署您的应用并将它上传到 Google Play。然后,Google 使用上传证书验证您的身份,并使用您的应用签名密钥重新签署 APK 以进行分发,如图 1 所示。(如果您还没有应用签名密钥,您可以在注册过程中生成一个。)

签署您的应用--手动签署 APK

图 1. 利用 Google Play 应用签名签署应用

当您使用 Google Play 应用签名时,如果您丢失您的上传密钥,或者该密钥受到攻击,您可以联系 Google 以撤销您的旧上传密钥并生成一个新的上传密钥。由于您的应用签名密钥受 Google 保护,因此,即使您更改上传密钥,您仍可以继续以原始应用更新的形式上传应用的新版本。

如需详细了解如何选择使用 Google Play 应用签名,请参阅管理您的应用签名密钥

自行管理您的密钥和密钥库

您可以选择自行管理您的应用签名密钥和密钥库,而不必使用 Google Play 签名。如果您选择自行管理您的应用签名密钥和密钥库,那么,您自行负责保障该密钥和密钥库的安全。您应当为密钥库选择一个强密码,并为密钥库中存储的每个私钥选择一个单独的强密码。您必须将密钥库存放在安全可靠的地方。如果您无法访问您的应用签名密钥,或者您的密钥受到攻击,Google 将无法为您恢复应用签名密钥,并且您将无法以原始应用更新的形式向用户发布您的应用的新版本。如需了解详细信息,请参阅下文的保护您的密钥

如果您自行管理您的应用签名密钥和密钥库,那么,当您签署您的 APK 时,您将使用您的应用签名密钥在本地签署它,并直接将已签署 APK 上传到 Google Play 商店以进行分发,如图 2 所示。

签署您的应用--手动签署 APK

签署 APK


无论您选择如何管理您的密钥和密钥库,您都可以使用 Android Studio 签署您的 APK(使用上传密钥或应用签名密钥),以手动方式或通过配置您的构建流程自动签署 APK。

如果您选择自行管理和保护您的应用签名密钥和密钥库,您将使用您的应用签名密钥签署您的 APK。如果您选择使用 Google Play 应用签名管理和保护您的应用签名密钥和密钥库,那么,您将使用您的上传密钥签署您的 APK。

生成密钥和密钥库

您可以使用 Android Studio 生成应用签名或上传密钥,步骤如下:

  1. 在菜单栏中,点击 Build > Generate Signed APK
  2. 从下拉菜单中选择一个模块,然后点击 Next
  3. 点击 Create new 以创建一个新密钥和密钥库。

  4. 在 New Key Store 窗口上,为您的密钥库和密钥提供以下信息,如图 3 所示。

    签署您的应用--手动签署 APK

    密钥库

    • Key store path:选择创建密钥库的位置。
    • Password:为您的密钥库创建并确认一个安全的密码。

    密钥

    • Alias:为您的密钥输入一个标识名。
    • Password:为您的密钥创建并确认一个安全的密码。此密码应当与您为密钥库选择的密码不同
    • Validity (years):以年为单位设置密钥的有效时长。密钥的有效期应至少为 25 年,以便您可以在应用的整个生命期内使用相同的密钥签署应用更新。
    • Certificate:为证书输入一些关于您自己的信息。此信息不会显示在应用中,但会作为 APK 的一部分包含在您的证书中。

    填写完表单后,请点击 OK

  5. 如果您想生成一个使用您的新密钥签署的 APK,则继续转到手动签署 APK,如果您只想生成一个密钥和密钥库而不签署 APK,则点击 Cancel
  6. 如果您想选择使用 Google Play 应用签名,则转到管理您的应用签名密钥,并按照说明设置 Google Play 应用签名。

手动签署 APK

您可以使用 Android Studio 手动生成签署的 APK,既可以一次生成一个 APK,也可以一次为多个构建变体生成 APK。除了手动签署 APK 外,您还可以将 Gradle 构建设置配置为在构建流程期间自动处理签署。本部分将介绍手动签署流程。如需详细了解如何在构建流程中签署应用,请参阅配置构建流程以自动签署您的 APK

要在 Android Studio 中手动签署用于发布的 APK,请按以下步骤操作:

  1. 点击 Build > Generate Signed APK 以打开 Generate Signed APK 窗口。(如果您刚刚按上述说明生成了一个密钥和密钥库,则此窗口已处于打开状态。)
  2. 在 Generate Signed APK Wizard 窗口上,选择一个密钥库和一个私钥,并为它们输入密码。(如果您刚刚在上一部分中创建密钥库,这些字段将自动填充。)然后,点击 Next

    :如果您使用 Google Play 应用签名,您应在此处指定您的上传密钥。如果改为自行管理您的应用签名密钥和密钥库,您应指定您的应用签名密钥。如需了解详细信息,请参阅上文的管理您的密钥

    签署您的应用--手动签署 APK

  3. 在下一个窗口上,为签署的 APK 选择一个目的地、选择构建类型、选择产品风味(如果适用),然后点击 Finish

    签署您的应用--手动签署 APK

    :如果您的项目使用多个产品风味,那么在 Windows/Linux 上按住 Ctrl 键或者在 Mac OS X 上按住 Command 键可以选择多个产品风味。Android Studio 将为选择的每个产品风味生成单独的 APK。

在流程完成后,您会在上面选择的目标文件夹中找到签署的 APK。现在,您可以通过像 Google Play 商店一样的应用市场或者您选择的机制分发签署的 APK。要详细了解如何将签署的 APK 发布到 Google Play 商店,请参阅开始发布。要详细了解其他分发选项,请阅读替代分发选项

为了确保用户将更新成功安装到您的应用中,您需要在应用的整个生命周期内使用相同的证书签署 APK。要详细了解使用相同密钥签署所有应用的各种好处,请参阅下面的签署注意事项。如需了解有关保护您的私钥和密钥库的详细信息,请参阅下文的保护您的密钥

配置构建流程以自动签署您的 APK

在 Android Studio 中,您可以创建一个签署配置并将其分配至您的发布构建类型,将您的项目配置为在构建流程中自动签署发布 APK。一个签署配置包含一个密钥库位置、密钥库密码、密钥别名和密钥密码。要使用 Android Studio 创建一个签署配置并将其分配至您的发布构建类型,请按以下步骤操作:

  1. 在 Project 窗口中,右键点击您的应用并点击 Open Module Settings
  2. 在 Project Structure 窗口左面板中的 Modules 下,点击您想要签署的模块。
  3. 点击 Signing 标签,然后点击 Add。 签署您的应用--手动签署 APK
  4. 选择您的密钥库文件,为此签署配置输入一个名称(因为您可能创建多个配置),然后输入所需的信息。

    签署您的应用--手动签署 APK

  5. 点击 Build Types 标签。
  6. 点击 release 构建。
  7. 在 Signing Config 下,选择您刚创建的签署配置。

    签署您的应用--手动签署 APK

  8. 点击 OK

现在,在您每一次使用 Android Studio 构建发布构建时,IDE 都会使用您指定的签署配置自动签署 APK。您可以在所构建模块项目目录内部的 build/outputs/apk/ 文件夹中找到签署的 APK。

在您创建签署配置时,您的签署信息将以纯文本形式包含到 Gradle 构建文件中。如果您是团队协作开发或者公开分享自己的代码,那么您应当从构建文件中移除签署信息并将其单独存储,从而确保此信息的安全。要详细了解如何从构建文件中移除您的签署信息,请参阅从您的构建文件中移除签署信息。要详细了解如何保证签署信息安全,请参阅保护您的密钥

以不同方式签署每个产品风味

如果您的应用使用多个产品风味并且您想要以不同方式签署每个风味,则可以创建更多签署配置并将其按风味分配:

  1. 在 Project 窗口中,右键点击您的应用并点击 Open Module Settings
  2. 在 Project Structure 窗口左面板中的 Modules 下,点击您想要签署的模块。
  3. 点击 Signing 标签,然后点击 Add。 签署您的应用--手动签署 APK
  4. 选择您的密钥库文件,为此签署配置输入一个名称(因为您可能创建多个配置),然后输入所需的信息。

    签署您的应用--手动签署 APK

  5. 如果需要,请重复第 3 步和第 4 步,直到您完成所有签署配置的创建。
  6. 点击 Flavors 标签。
  7. 点击您想要配置的风味,然后从 Signing Config 下拉菜单中选择合适的签署配置。签署您的应用--手动签署 APK

    重复操作以配置任何其他产品风味。

  8. 点击 OK

您还可以在 Gradle 配置文件中指定您的签署设置。如需了解详细信息,请参阅配置签署设置

签署 Android Wear 应用

如果您构建一个 Android Wear 应用,则签署此应用的流程不同于本页面上介绍的流程。请参阅与打包和发布 Android Wear 应用有关的信息。

签署注意事项


在应用的预期生命周期内,您应使用相同证书签署所有 APK。这么做的原因有多个:

  • 应用升级:当系统安装应用的更新时,它会比较新版本和现有版本中的证书。如果证书匹配,则系统允许更新。如果您使用不同的证书签署新版本,则必须为应用分配另一个软件包名称 - 在此情况下,用户将新版本作为全新应用安装。
  • 应用模块化:Android 允许通过相同证书签署的多个 APK 在同一个进程中运行(如果应用请求这样),以便系统将它们视为单个应用。通过此方式,您可以在模块中部署您的应用,且用户可以独立更新每个模块。
  • 通过权限共享代码/数据:Android 提供基于签名的权限执行,以便应用可以将功能展示给使用指定证书签署的另一应用。通过使用同一个证书签署多个 APK 并使用基于签名的权限检查功能,您的应用可采用安全的方式共享代码和数据。

如果您计划支持升级应用,请确保您的应用签名密钥的有效期超出该应用的预期生命周期。建议有效期为 25 年或以上。当密钥有效期过期后,用户将不能再无缝升级到应用的新版本。

如果您计划在 Google Play 上发布您的应用,您用于签署这些 APK 的密钥的有效期必须在 2033 年 10 月 22 日以后结束。Google Play 强制执行此要求,以确保在新版本可用时,用户可以无缝升级应用。如果您使用 Google Play 应用签名,则 Google 可确保您的应用正确签署,并能够在它们的整个生命周期内接收更新。

保护您的密钥


如果您选择自行管理和保护您的应用签名密钥和密钥库(而不是选择使用 Google Play 应用签名),则保障您的应用签名密钥安全对于您和用户而言都非常重要。如果您允许某人使用您的密钥,或者将您的密钥库和密码放在了不安全的地方,以致于第三方可以找到和使用它们,则会损害您的作者身份和用户对您的信任。

:如果您使用 Google Play 应用签名,则使用 Google 的基础架构会保障您的应用签名密钥安全。您还应按如下所述保证您的上传密钥安全。如果您的上传密钥受到攻击,您可以联系 Google 以撤销它并收到一个新的上传密钥。

如果某个第三方在您不知情或未经授权的情况下设法取得您的密钥,此人可能会签署和分发应用,从而恶意替换您的原版应用或损坏它们。另外,此人还可能利用您的身份签署和分发应用,从而攻击其他应用或系统本身,损坏或窃取用户数据。

您应用的所有将来版本签署时都需要使用您的私钥。如果您的密钥丢失或存放不当,您将无法发布您的现有应用的更新。您无法重新生成以前生成的密钥。

您作为开发者实体的声誉取决于您能否每时每刻正确保护您的应用签名密钥,直至密钥过期。以下是针对保护密钥安全的一些提示:

  • 为密钥库和密钥选择强密码。
  • 请勿将您的私钥赠与或借给任何人,也不要让未经授权的人员知道您的密钥库和密钥密码。
  • 将包含私钥的密钥库文件存放在安全可靠的地方。

通常情况下,只要您在生成、使用和存储密钥时遵循通用的注意事项,就可以保障密钥的安全。

从您的构建文件中移除签署信息

在您创建签署配置时,Android Studio 会以纯文本形式将您的签署信息添加到模块的 build.gradle 文件中。如果您是团队协作开发或者将您的代码开源,那么您应当将此敏感信息从构建文件中移出,以免被其他人轻易获取。为此,您应创建一个单独的属性文件来存储安全信息并按以下步骤操作,在您的构建文件中引用该文件:

  1. 创建一个签署配置,并将其分配至一个或多个构建类型。这些说明假设您已经按照上面配置构建流程以自动签署您的 APK 部分所述,为发布构建类型配置了一个签署配置。
  2. 在项目的根目录下创建一个名为 keystore.properties 的文件。此文件应当包含您的签署信息,如下所示:
    storePassword=myStorePassword
    keyPassword=mykeyPassword
    keyAlias=myKeyAlias
    storeFile=myStoreFileLocation
  3. 在模块的 build.gradle 文件中,于 android {} 块的前面添加用于加载 keystore.properties 文件的代码。
    ...
    
    // Create a variable called keystorePropertiesFile, and initialize it to your
    // keystore.properties file, in the rootProject folder.
    def keystorePropertiesFile = rootProject.file("keystore.properties") // Initialize a new Properties() object called keystoreProperties.
    def keystoreProperties = new Properties() // Load your keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) android {
        ...
    }

    :您可以选择将 keystore.properties 文件存储在其他位置(例如,存储在模块文件夹中而不是项目的根文件夹中,或者如果您使用持续集成工具,也可以存储在构建服务器上)。在这种情况下,您应当修改上面的代码,以便使用实际 keystore.properties 文件的位置正确初始化 keystorePropertiesFile

  4. 您可以使用语法 keystoreProperties['propertyName'] 引用存储在 keystoreProperties 中的属性。修改模块 build.gradle 文件的 signingConfigs 块,以便使用此语法引用存储在 keystoreProperties 中的签署信息。
    android {
        signingConfigs {
            config {
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
                storeFile file(keystoreProperties['storeFile'])
                storePassword keystoreProperties['storePassword']
            }
        }
        ...
      }
  5. 打开 Build Variants 工具窗口并确保已选择发布构建类型。
  6. 点击 Build > Build APK 以构建您的发布构建,并确认 Android Studio 已在模块的 build/outputs/apk/ 目录中创建一个签署的 APK。

由于您的构建文件不再包含敏感信息,您现在可以将其包含在源控制中或者上传到共享的代码库。务必保证 keystore.properties 文件的安全。您可能需要将其从您的源控制系统中移除。

从命令行构建和签署您的应用


不需要 Android Studio 也可以签署您的应用。您可以通过 apksigner 工具从命令行签署您的应用,或在构建期间配置 Gradle 来签署您的应用。无论使用哪一个方式,您必须首先使用 keytool 生成一个私钥。例如:

keytool -genkey -v -keystore my-release-key.jks
-keyalg RSA -keysize 2048 -validity 10000 -alias my-alias

keytool 位于 JDK 中的 bin/ 目录中。要从 Android Studio 查找您的 JDK,选择 File > Project Structure,然后点击 SDK Location,您将看到 JDK location

本示例会提示您输入密钥库和密钥的密码,并为您的密钥提供“Distinguished Name”字段。随后,它生成一个名为 my-release-key.jks 的密钥库文件,将它保存在当前目录中(您可以根据需要移动它)。此密钥库包含一个有效期为 10,000 天的密钥。

现在,您可以构建一个未签署的 APK 并手动签署它,也可以配置 Gradle 以签署您的 APK

构建未签署 APK 并手动签署它

  1. 打开命令行,然后导航至项目的根目录 - 在 Android Studio 中,选择 View > Tool Windows > Terminal。然后调用 assembleRelease 任务:
    gradlew assembleRelease

    这将在 project_name/module_name/build/outputs/apk/ 中创建一个名为 module_name-unsigned.apk 的 APK。此 APK 此时处于未签署且未对齐的状态,使用您的私钥签署后才能安装。

  2. 使用 zipalign 对齐未签署的 APK:

    zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk
    

    zipalign 可以确保所有未压缩的数据的开头均相对于文件开头部分执行特定的字节对齐,这样可减少应用消耗的 RAM 量。

  3. 通过 apksigner 使用您的私钥签署 APK:

    apksigner sign --ks my-release-key.jks --out my-app-release.apk my-app-unsigned-aligned.apk
    

    在本例中,在使用单密钥库文件 my-release-key.jks 中存储的私钥和证书签署 APK 后,将以 my-app-release.apk 的形式输出签署的 APK。

    apksigner 工具支持其他签署选项,包括使用单独的私钥和证书文件签署 APK 文件和使用多个签署人签署 APK。有关更多详情,请参阅 apksigner参考。

    :要使用 apksigner 工具,您必须已安装 Android SDK Build Tool 的修订版 24.0.3 或更高版本。您可以使用 SDK 管理器更新此软件包。

  4. 验证您的 APK 是否已签署:

    apksigner verify my-app-release.apk
    

配置 Gradle 以签署您的 APK

  1. 打开模块级 build.gradle 文件并添加带有 storeFilestorePasswordkeyAlias 和 keyPassword 条目的 signingConfigs {} 块,然后将该对象传递到您的构建类型中的 signingConfig 属性。例如:
    android {
        ...
        defaultConfig { ... }
        signingConfigs {
            release {
                storeFile file("my-release-key.jks")
                storePassword "password"
                keyAlias "my-alias"
                keyPassword "password"
            }
        }
        buildTypes {
            release {
                signingConfig signingConfigs.release
                ...
            }
        }
    }

    由于 Gradle 会读取相对于 build.gradle 的路径,因此仅当 my-release-key.jks 与 build.gradle 文件在同一目录中,以上示例才有效。

    :在此情况下,密钥库和密钥密码可直接在 build.gradle 文件中查看。为提升安全性,您应从您的构建文件中移除签署信息

  2. 在您的项目根目录中打开一个命令行,并调用 assembleRelease 任务:
    gradlew assembleRelease

这将在 project_name/module_name/build/outputs/apk/ 中创建一个名为 module_name-release.apk 的 APK。这个 APK 文件已经使用 build.gradle文件中指定的私钥签署,并使用 zipalign 进行了对齐。

现在,您已使用签名密钥配置了发布构建,该构建类型可以执行“安装”任务。因此,您可以通过 installRelease 任务在模拟器或设备上构建、对齐、签署和安装发行 APK。

使用您的私钥签署的 APK 已做好分发准备,但您首先应阅读有关如何发布您的应用的详细信息并查看 Google Play 发布检查单

签署您的应用--手动签署 APK