Android 要求所有 APK 在安装到设备或更新之前都必须使用证书进行数字签名。当使用 Android 应用包 发布时,您需要在将应用包上传到 Play Console 之前使用上传密钥对其进行签名,Play 应用签名将处理其余操作。对于在 Play 商店或其他商店中使用 APK 分发的应用,您必须手动为上传签名 APK。
本页面将引导您了解与应用签名和安全性相关的一些重要概念,如何使用 Android Studio 为发布到 Google Play 的应用签名,以及如何配置 Play 应用签名。
以下是将新应用签名并发布到 Google Play 可能需要采取的步骤的高级概述
如果您的应用已发布到 Google Play 商店并使用现有的应用签名密钥,或者您希望为新应用选择应用签名密钥而不是让 Google 生成,请按照以下步骤操作
- 使用应用的签名密钥对您的应用签名。
- 将您的应用的签名密钥上传到 Play 应用签名。
- (推荐) 为应用的未来更新生成并注册上传证书
- 将您的应用上传到 Google Play
- 准备和推出应用版本
本页面还探讨了如何在将应用上传到其他应用商店时管理自己的密钥。如果您不使用 Android Studio 或希望从命令行签名应用,请了解如何使用apksigner
。
Play 应用签名
使用 Play 应用签名,Google 会为您管理和保护应用的签名密钥,并使用它来签署用于分发的 APK。并且,由于应用捆绑包将构建和签名 APK 的工作推迟到 Google Play 商店,因此您需要在上传应用捆绑包之前配置 Play 应用签名。这样做可以使您受益于以下方面
- 使用 Android 应用捆绑包并支持 Google Play 的高级交付模式。Android 应用捆绑包使您的应用更小,发布更简单,并且可以利用功能模块并提供即时体验。
- 提高签名密钥的安全性,并可以使用单独的上传密钥来签署您上传到 Google Play 的应用捆绑包。
密钥升级允许您更改应用签名密钥,以防现有密钥泄露或您需要迁移到加密强度更高的密钥
Play 应用签名使用两个密钥:应用签名密钥和上传密钥,在密钥和密钥库部分中将对其进行更详细的说明。您保留上传密钥并使用它来签署应用,以便上传到 Google Play 商店。Google 使用上传证书来验证您的身份,并使用您的应用签名密钥签署您的 APK,以便分发,如图 1 所示。通过使用单独的上传密钥,您可以请求重置上传密钥,如果您的密钥丢失或泄露。
相比之下,对于尚未选择加入 Play 应用签名的应用,如果您丢失了应用的签名密钥,则将无法更新您的应用。
您的密钥存储在 Google 用于存储自身密钥的相同基础架构上,这些密钥受到 Google 密钥管理服务的保护。您可以阅读Google Cloud 安全白皮书,详细了解 Google 的技术基础架构。
当您使用 Play 应用签名时,如果您丢失了上传密钥或上传密钥遭到泄露,则可以在 Play Console 中请求重置上传密钥。由于您的应用签名密钥受到 Google 的保护,即使您更改了上传密钥,您也可以继续将新版本应用作为原始应用的更新上传。要了解更多信息,请阅读重置丢失或泄露的私有上传密钥。
下一节将描述一些与应用签名和安全性相关的重要术语和概念。如果您希望跳过此部分并了解如何准备应用以上传到 Google Play 商店,请转到为发布签名应用。
密钥库、密钥和证书
Java 密钥库(.jks 或 .keystore)是作为证书和私钥存储库的二进制文件。
公钥证书(.der
或 .pem
文件),也称为数字证书或身份证书,包含公钥/私钥对的公钥,以及一些其他元数据,用于识别持有相应私钥的所有者(例如,姓名和位置)。
以下是您应该了解的不同类型的密钥
- 应用签名密钥:用于签署安装在用户设备上的 APK 的密钥。作为 Android 安全更新模型的一部分,签名密钥在应用的生命周期内永远不会更改。应用签名密钥是私密的,必须保密。但是,您可以共享使用应用签名密钥生成的证书。
上传密钥:在您上传应用以进行使用 Google Play 签名应用之前,用于签署应用捆绑包或 APK 的密钥。您必须将上传密钥保密。但是,您可以共享使用上传密钥生成的证书。您可以通过以下方式之一生成上传密钥
- 如果您选择在选择加入时让 Google 为您生成应用签名密钥,则用于为发布签名应用的密钥将被指定为您的上传密钥。
- 如果您在选择加入新应用或现有应用时向 Google 提供应用签名密钥,则可以选择在选择加入期间或之后生成新的上传密钥以提高安全性。
- 如果您没有生成新的上传密钥,则将继续使用应用签名密钥作为上传密钥来签署每个版本。
提示:为确保密钥安全,最好确保应用签名密钥和上传密钥不同。
与 API 提供商合作
您可以从 Play Console 中的发布 > 设置 > 应用签名页面下载应用签名密钥和上传密钥的证书。Play Console。这用于向 API 提供商注册公钥;它旨在共享,因为它不包含您的私钥。
证书指纹是证书的简短唯一表示形式,API 提供商通常会与包名称一起请求它,以注册使用其服务的应用。上传和应用签名证书的 MD5、SHA-1 和 SHA-256 指纹可以在 Play Console 的应用签名页面中找到。还可以通过从同一页面下载原始证书(.der
)来计算其他指纹。
签署调试版本
在从 IDE 运行或调试项目时,Android Studio 会使用 Android SDK 工具生成的调试证书自动签署您的应用。首次在 Android Studio 中运行或调试项目时,IDE 会自动在$HOME/.android/debug.keystore
中创建调试密钥库和证书,并设置密钥库和密钥密码。
由于调试证书是由构建工具创建的,并且设计上不安全,因此大多数应用商店(包括 Google Play 商店)不接受使用调试证书签署的应用进行发布。
Android Studio 会自动将调试签名信息存储在签名配置中,因此您不必每次调试时都输入它。签名配置是一个对象,包含签署应用所需的所有信息,包括密钥库位置、密钥库密码、密钥名称和密钥密码。
有关如何构建和运行应用以进行调试的更多信息,请参阅构建和运行应用。
调试证书到期
用于签署应用以进行调试的自签名证书在其创建日期起 30 年后到期。当证书到期时,您会收到构建错误。
要解决此问题,只需删除存储在以下位置之一的debug.keystore
文件
- 在 OS X 和 Linux 上为
~/.android/
- 在 Windows XP 上为
C:\Documents and Settings\user\.android\
- 在 Windows Vista 和 Windows 7、8 和 10 上为
C:\Users\user\.android\
下次构建并运行应用的调试版本时,Android Studio 会重新生成新的密钥库和调试密钥。
为发布到 Google Play 签名应用
准备好发布应用后,您需要签署应用并将其上传到应用商店(例如 Google Play)。首次将应用发布到 Google Play 时,您还必须配置 Play 应用签名。对于 2021 年 8 月之前创建的应用,Play 应用签名是可选的。本节将向您展示如何正确地为发布签名应用以及配置 Play 应用签名。
生成上传密钥和密钥库
如果您还没有上传密钥(在配置 Play 应用签名时很有用),您可以使用 Android Studio 生成一个,方法如下
- 在菜单栏中,点击构建 > 生成签名捆绑包/APK。
- 在生成签名捆绑包或 APK对话框中,选择Android 应用捆绑包或APK,然后点击下一步。
- 在密钥库路径字段下方,点击创建新。
在新密钥库窗口中,为密钥库和密钥提供以下信息,如图 2 所示。
密钥库
- 密钥库路径:选择密钥库的创建位置。此外,应在位置路径的末尾添加文件名,并使用
.jks
扩展名。 - 密码:创建并确认密钥库的安全密码。
- 密钥库路径:选择密钥库的创建位置。此外,应在位置路径的末尾添加文件名,并使用
密钥
- 别名:输入密钥的识别名称。
- 密码:创建并确认密钥的安全密码。这应该与您的密钥库密码相同。(有关更多信息,请参阅已知问题)
- 有效期(年):设置密钥的有效期(以年为单位)。您的密钥应至少有效 25 年,以便您可以在应用的生命周期内使用相同的密钥签署应用更新。
- 证书:输入有关您自己的某些信息以用于证书。此信息不会显示在您的应用中,但会作为 APK 的一部分包含在您的证书中。
完成表单后,点击确定。
如果您想使用您的上传密钥构建和签名您的应用,请继续阅读有关如何使用您的上传密钥签名您的应用的部分。如果您只想生成密钥和密钥库,请点击取消。
使用您的密钥签名您的应用
如果您已经有上传密钥,请使用它来签名您的应用。如果您的应用已经签名并使用现有的应用签名密钥发布到 Google Play 商店,请使用它来签名您的应用。您以后可以生成并注册一个单独的上传密钥与 Google Play 合作,以签名和上传您应用的后续更新。
要使用 Android Studio 签名您的应用,请按照以下步骤操作
- 如果您当前没有打开生成签名捆绑包或 APK对话框,请点击构建 > 生成签名捆绑包/APK。
- 在生成签名捆绑包或 APK对话框中,选择Android 应用捆绑包或APK,然后点击下一步。
- 从下拉菜单中选择一个模块。
指定密钥库的路径、密钥的别名,并输入两者的密码。如果您尚未准备您的上传密钥库和密钥,请先生成上传密钥和密钥库,然后返回完成此步骤。
点击下一步。
在下一个窗口(如图 4 所示)中,选择已签名应用的目标文件夹,选择构建类型,如果适用,选择产品风格。
如果您正在构建和签名 APK,则需要选择您的应用要支持的签名版本。要了解更多信息,请阅读有关应用签名方案的内容
点击创建。
Android Studio 完成已签名应用的构建后,您可以通过点击弹出通知中相应的选项(如图 5 所示)来找到或分析您的应用。
现在您已准备好将您的应用加入 Play 应用签名并上传您的应用以供发布。如果您不熟悉应用发布流程,您可能需要阅读发布概述。否则,请继续阅读有关如何将您的应用上传到 Play Console的页面。
使用 Play 应用签名
如本页面前面所述,配置Play 应用签名是通过 Google Play 发布应用所必需的(2021 年 8 月之前创建的应用除外,这些应用可以继续分发自签名 APK)。您需要采取的步骤取决于您的应用是否尚未发布到 Google Play,或者您的应用是否已签名并在 2021 年 8 月之前使用现有的应用签名密钥发布。
配置新应用
要为尚未发布到 Google Play 的应用配置签名,请按以下步骤操作
- 如果您尚未这样做,请生成上传密钥并使用该上传密钥签名您的应用。
- 登录您的Play Console。
- 按照准备和推出您的版本的步骤创建新版本。
- 选择发布轨道后,请在应用签名部分按如下方式配置应用签名
- 要让 Google Play 为您生成应用签名密钥并使用它来签名您的应用,您无需执行任何操作。您用于签名第一个版本的密钥将成为您的上传密钥,您应该使用它来签名未来的版本。
- 要使用开发人员帐户中另一个应用的相同密钥,请选择更改应用签名密钥 > 使用此帐户中另一个应用的相同密钥,选择一个应用,然后点击继续。
- 要提供您自己的签名密钥供 Google 在签名您的应用时使用,请选择更改应用签名密钥,然后选择其中一个导出和上传选项,该选项允许您安全地上传私钥及其公钥证书。
在名为应用捆绑包的部分中,点击浏览文件以找到并上传使用您的上传密钥签名的应用。有关发布应用的更多信息,请参阅准备和推出您的版本。在您配置 Play 应用签名后发布应用时,Google Play 会为您生成(除非您上传现有密钥)并管理您的应用的签名密钥。只需在将后续更新上传到 Google Play 之前,使用应用的上传密钥对这些更新进行签名即可。
如果您需要为您的应用创建新的上传密钥,请转到有关如何重置丢失或遭到破坏的私有上传密钥的部分。
加入现有应用
如果您正在更新已使用现有应用签名密钥发布到 Google Play 的应用,您可以按以下步骤加入 Play 应用签名
- 登录您的Play Console并导航到您的应用。
- 在左侧菜单中,点击发布 > 设置 > 应用签名。
- 如果适用,请查看服务条款并选择接受。
- 选择最能描述您想要上传到 Google Play 的签名密钥的选项,然后按照显示的说明进行操作。例如,如果您正在使用 Java 密钥库作为签名密钥,请选择从 Java 密钥库上传新的应用签名密钥,然后按照说明下载并运行 PEPK 工具,并上传包含您加密密钥的生成文件。
- 点击加入。
您现在应该会看到一个页面,其中包含您的应用的签名和上传证书的详细信息。Google Play 现在在将您的应用部署到用户时使用您的现有密钥对其进行签名。但是,Play 应用签名最重要的优势之一是能够将用于签名您上传到 Google Play 的工件的密钥与 Google Play 用于签名您的应用以分发给用户的密钥分开。因此,请考虑按照下一节中的步骤生成并注册一个单独的上传密钥。
生成并注册上传证书
当您发布未由上传密钥签名的应用时,Google Play Console 会提供注册一个密钥以供应用未来更新使用的选项。虽然这是一个可选步骤,但建议您使用与 Google Play 用于分发应用给用户的密钥分开的密钥发布您的应用。这样,Google 会确保您的签名密钥安全,并且您可以选择重置丢失或遭到破坏的私有上传密钥。本节介绍如何创建上传密钥、从中生成上传证书以及将该证书注册到 Google Play 以供将来更新您的应用。
以下是您在 Play Console 中看到注册上传证书选项的情况
- 当您发布一个使用签名密钥签名的并加入 Play 应用签名的新应用时。
- 当您即将发布一个已加入 Play 应用签名但使用其签名密钥签名的现有应用时。
如果您没有发布已加入 Play 应用签名的现有应用的更新,并且想要注册上传证书,请完成以下步骤,然后继续下一节,了解如何重置丢失或遭到破坏的私有上传密钥。
如果您尚未这样做,请生成上传密钥和密钥库。
创建上传密钥和密钥库后,您需要使用keytool
从您的上传密钥生成公钥证书,并使用以下命令
$ keytool -export -rfc -keystore your-upload-keystore.jks -alias upload-alias -file output_upload_certificate.pem
现在您有了上传证书,请在 Play Console 中收到提示时或重置上传密钥时将其注册。
升级您的应用签名密钥
在某些情况下,您可能希望更改应用的签名密钥。例如,因为您想要一个加密强度更高的密钥,或者您的签名密钥已被泄露。但是,由于用户只有在更新使用相同的签名密钥签名时才能更新您的应用,因此很难更改已发布应用的签名密钥。
如果您将应用发布到 Google Play,则可以通过 Play Console 升级已发布应用的签名密钥——您的新密钥用于为 Android 13 及更高版本上的安装和应用更新签名,而您的旧应用签名密钥用于为较早版本的 Android 上的用户签名更新。
要了解更多信息,请阅读升级您的应用签名密钥。
重置丢失或遭到破坏的私有上传密钥
如果您丢失了私有上传密钥或您的私钥已被泄露,您可以创建一个新的密钥,并在 Play Console 中请求重置上传密钥。
配置构建过程以自动签名您的应用
在 Android Studio 中,您可以通过创建签名配置并将其分配给您的发布构建类型,配置您的项目以在构建过程中自动签名应用的发布版本。签名配置包含密钥库位置、密钥库密码、密钥别名和密钥密码。要使用 Android Studio 创建签名配置并将其分配给您的发布构建类型,请完成以下步骤
- 在项目窗口中,右键点击您的应用,然后点击打开模块设置。
- 在项目结构窗口中,在左侧面板的模块下,点击您要签名的模块。
- 点击签名选项卡,然后点击添加 。
-
选择您的密钥库文件,为该签名配置输入一个名称(因为您可能创建多个),然后输入所需的信息。
- 点击Build Types选项卡。
- 点击release构建。
-
在Signing Config下,选择您刚刚创建的签名配置。
- 点击OK。
现在,每次您通过选择 Android Studio 中Build > Build Bundle(s) / APK(s)下的选项构建发布构建类型时,IDE 将自动使用您指定的签名配置对您的应用进行签名。您可以在正在构建的模块的项目目录中的build/outputs/
目录中找到已签名的 APK 或应用包。
创建签名配置时,您的签名信息将以纯文本形式包含在您的 Gradle 构建文件中。如果您在一个团队中工作或公开共享您的代码,则应通过将其从构建文件中删除并单独存储来确保您的签名信息安全。您可以在从构建文件中删除签名信息中阅读有关如何从构建文件中删除签名信息的更多信息。有关保持签名信息安全的更多信息,请参阅下面的保护您的密钥。
为每个产品风格单独签名
如果您的应用使用产品风格,并且您希望为每个风格单独签名,则可以创建其他签名配置并按风格分配它们。
- 在项目窗口中,右键点击您的应用,然后点击打开模块设置。
- 在项目结构窗口中,在左侧面板的模块下,点击您要签名的模块。
- 点击签名选项卡,然后点击添加 。
-
选择您的密钥库文件,为该签名配置输入一个名称(因为您可能创建多个),然后输入所需的信息。
- 根据需要重复步骤 3 和 4,直到您创建所有签名配置。
- 点击Flavors选项卡。
- 点击您要配置的风味,然后从Signing Config下拉菜单中选择相应的签名配置。
重复以配置任何其他产品风格。
- 点击OK。
您也可以在 Gradle 配置文件中指定签名设置。有关更多信息,请参阅配置签名设置。
运行签名报告
要获取应用每个变体的签名信息,请在 Android Studio 中运行 Gradle signingReport
任务。
- 选择View > Tool Windows > Gradle打开 Gradle 工具窗口。
- 选择YourApp > Tasks > android > signingReport运行报告。
管理您自己的签名密钥
如果您选择不加入 Play 应用签名(仅适用于 2021 年 8 月之前创建的应用),您可以管理您自己的应用签名密钥和密钥库。请记住,您负责保护密钥和密钥库。此外,您的应用将无法支持 Android 应用包、Play 功能交付和 Play 资产交付。
当您准备好创建自己的密钥和密钥库时,请确保首先为您的密钥库选择一个强密码,并为存储在密钥库中的每个私钥选择一个单独的强密码。您必须将密钥库保存在安全的地方。如果您丢失了对应用签名密钥的访问权限或您的密钥遭到泄露,Google 无法为您检索应用签名密钥,您将无法向用户发布应用的新版本作为对原始应用的更新。有关更多信息,请参阅下面的保护您的密钥。
如果您管理您自己的应用签名密钥和密钥库,当您对 APK 进行签名时,您将使用您的应用签名密钥在本地对其进行签名,并将签名的 APK 直接上传到 Google Play 商店进行分发,如图 12 所示。
当您使用Play 应用签名时,Google 会保护您的签名密钥安全,并确保您的应用正确签名并能够在其整个生命周期中接收更新。但是,如果您决定自己管理应用签名密钥,则需要考虑以下几点。
签名注意事项
您应该在应用的预期生命周期内使用相同的证书对应用进行签名。您应该这样做有几个原因。
- 应用升级:当系统安装应用更新时,它会将新版本中的证书与现有版本中的证书进行比较。如果证书匹配,则系统允许更新。如果您使用不同的证书对新版本进行签名,则必须为应用分配不同的包名称——在这种情况下,用户会将新版本安装为一个全新的应用。
- 应用模块化:Android 允许由相同证书签名的 APK 在同一进程中运行,如果应用如此请求,以便系统将它们视为单个应用。这样,您就可以模块化部署您的应用,用户可以独立更新每个模块。
- 通过权限共享代码/数据:Android 提供基于签名的权限执行,以便应用可以向使用指定证书签名的另一个应用公开功能。通过使用相同的证书对多个 APK 进行签名并使用基于签名的权限检查,您的应用可以安全地共享代码和数据。
如果您计划支持应用升级,请确保您的应用签名密钥的有效期超过该应用的预期生命周期。建议有效期为 25 年或更长。当密钥的有效期过期时,用户将无法再无缝升级到应用的新版本。
如果您计划在 Google Play 上发布您的应用,则用于对应用进行签名的密钥必须具有在 2033 年 10 月 22 日之后结束的有效期。Google Play 实施此要求是为了确保用户在有新版本可用时能够无缝升级应用。
保护您的密钥
如果您选择自己管理和保护应用签名密钥和密钥库(而不是选择加入Play 应用签名),那么保护您的应用签名密钥对您和用户都至关重要。如果您允许他人使用您的密钥,或者如果您将密钥库和密码放在不安全的位置,以便第三方可以找到并使用它们,那么您的创作身份和用户的信任就会受到损害。
如果第三方在您不知情或未经您许可的情况下获取您的应用签名密钥,则该人可以签名和分发恶意替换您的真实应用或损坏它们的应用。这样的人还可以以您的身份签名和分发攻击其他应用或系统本身的应用,或者损坏或窃取用户数据。
您的私钥是签名应用所有未来版本所必需的。如果您丢失或放错位置了密钥,您将无法发布现有应用的更新。您无法重新生成以前生成的密钥。
您作为开发者实体的声誉取决于您始终如一地正确保护您的应用签名密钥,直到密钥过期。以下是一些保护密钥安全的技巧。
- 为密钥库和密钥选择强密码。
- 不要向任何人提供或出借您的私钥,也不要让未经授权的人员知道您的密钥库和密钥密码。
- 将包含私钥的密钥库文件保存在安全的地方。
一般来说,如果您在生成、使用和存储密钥时遵循常识性预防措施,它将保持安全。
从构建文件中删除签名信息
创建签名配置时,Android Studio 会将您的签名信息以纯文本形式添加到模块的build.gradle
文件中。如果您与团队合作或开源您的代码,则应将此敏感信息移出构建文件,以使其不易被其他人访问。为此,您应该创建一个单独的属性文件来存储安全信息,并在构建文件中按如下方式引用该文件。
- 创建一个签名配置,并将其分配给一个或多个构建类型。这些说明假设您已为发布构建类型配置了一个签名配置,如上文配置构建过程以自动对您的应用进行签名中所述。
- 在项目的根目录中创建一个名为
keystore.properties
的文件。此文件应包含您的签名信息,如下所示。storePassword=myStorePassword keyPassword=mykeyPassword keyAlias=myKeyAlias storeFile=myStoreFileLocation
- 在模块的
build.gradle
文件中,添加代码以在android {}
块之前加载keystore.properties
文件。Groovy
... // 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 { ... }
Kotlin
... import java.util.Properties import java.io.FileInputStream // Create a variable called keystorePropertiesFile, and initialize it to your // keystore.properties file, in the rootProject folder. val keystorePropertiesFile = rootProject.file("keystore.properties") // Initialize a new Properties() object called keystoreProperties. val keystoreProperties = Properties() // Load your keystore.properties file into the keystoreProperties object. keystoreProperties.load(FileInputStream(keystorePropertiesFile)) android { ... }
注意:您可以选择将
keystore.properties
文件存储在其他位置(例如,在模块文件夹而不是项目的根文件夹中,或者如果您使用持续集成工具,则存储在构建服务器上)。在这种情况下,您应该修改上面的代码以使用实际的keystore.properties
文件的位置正确初始化keystorePropertiesFile
。 - 您可以使用语法
keystoreProperties['propertyName']
引用存储在keystoreProperties
中的属性。修改模块的build.gradle
文件的signingConfigs
块以使用此语法引用存储在keystoreProperties
中的签名信息。Groovy
android { signingConfigs { config { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } ... }
Kotlin
android { signingConfigs { create("config") { keyAlias = keystoreProperties["keyAlias"] as String keyPassword = keystoreProperties["keyPassword"] as String storeFile = file(keystoreProperties["storeFile"] as String) storePassword = keystoreProperties["storePassword"] as String } } ... }
- 打开Build Variants工具窗口并确保选择了发布构建类型。
- 选择Build > Build Bundle(s) / APK(s)下的选项以构建发布构建的 APK 或应用包。您应该在模块的
build/outputs/
目录中看到构建输出。
由于您的构建文件不再包含敏感信息,因此您现在可以将其包含在源代码管理中或上传到共享代码库中。请务必保护keystore.properties
文件安全。这可能包括将其从源代码控制系统中删除。