Android 要求所有 APK 在安装到设备或更新之前都必须使用证书进行数字签名。使用Android 应用包发布时,需要先使用上传密钥对应用包进行签名,然后才能将其上传到 Play 管理中心,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 安全更新模型的一部分,签名密钥在应用的整个生命周期中都不会更改。应用签名密钥是私密的,必须保密。但是,您可以共享使用您的应用签名密钥生成的证书。
上传密钥:用于在上传应用包或 APK 以进行 使用 Google Play 进行应用签名 之前对其进行签名的密钥。您必须将上传密钥保密。但是,您可以共享使用您的上传密钥生成的证书。您可以通过以下方式之一生成上传密钥:
- 如果您选择在选择加入时让 Google 为您生成应用签名密钥,则用于 为发布签名您的应用 的密钥将被指定为您的上传密钥。
- 如果您在选择加入新应用或现有应用时向 Google 提供应用签名密钥,则可以选择在选择加入期间或之后生成新的上传密钥以提高安全性。
- 如果您不生成新的上传密钥,则将继续使用您的应用签名密钥作为上传密钥来为每个版本签名。
提示:为了确保密钥安全,最好确保您的应用签名密钥和上传密钥不同。
与 API 提供商合作
您可以从 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
文件:
~/.android/
(在 OS X 和 Linux 上)C:\Documents and Settings\user\.android\
(在 Windows XP 上)C:\Users\user\.android\
(在 Windows Vista 和 Windows 7、8 和 10 上)
下次构建并运行应用的调试版本时,Android Studio 会重新生成新的密钥库和调试密钥。
为发布到 Google Play 签名您的应用
准备好发布应用后,您需要对应用进行签名并将其上传到应用商店(例如 Google Play)。首次将应用发布到 Google Play 时,还必须配置 Play 应用签名。对于 2021 年 8 月之前创建的应用,Play 应用签名是可选的。本节将向您展示如何正确地为发布签名您的应用和配置 Play 应用签名。
生成上传密钥和密钥库
如果您还没有上传密钥(在配置 Play 应用签名时很有用),您可以使用 Android Studio 生成一个,方法如下:
- 在菜单栏中,点击构建 > 生成签名 Bundle/APK。
- 在生成签名 Bundle 或 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 创建签名配置并将其分配给您的发布构建类型,请完成以下步骤
- 在项目窗口中,右键单击您的应用,然后点击打开模块设置。
- 在项目结构窗口中,左侧面板的模块下,点击您要签名的模块。
- 点击签名选项卡,然后点击添加 。
-
选择您的密钥库文件,输入此签名配置的名称(因为您可能创建多个),然后输入所需的信息。
- 点击构建类型选项卡。
- 点击发布构建。
-
在签名配置下,选择您刚刚创建的签名配置。
- 点击确定。
现在,每次您在 Android Studio 中选择构建 > 构建 Bundle(s)/APK(s) 下的选项来构建您的发行版构建类型时,IDE 将使用您指定的签名配置自动签名您的应用。您可以在正在构建的模块的项目目录内的 build/outputs/
目录中找到已签名的 APK 或应用包。
创建签名配置时,您的签名信息将以纯文本形式包含在您的 Gradle 构建文件中。如果您在一个团队中工作或公开共享您的代码,则应通过将其从构建文件中删除并单独存储来确保您的签名信息安全。您可以在从构建文件中删除签名信息中阅读有关如何从构建文件中删除签名信息的更多信息。有关保持签名信息安全的更多信息,请参阅下面的保护您的密钥安全。
对每个产品风格进行不同的签名
如果您的应用使用产品风格,并且您希望对每个风格进行不同的签名,您可以创建额外的签名配置并按风格分配它们。
- 在项目窗口中,右键单击您的应用,然后点击打开模块设置。
- 在项目结构窗口中,左侧面板的模块下,点击您要签名的模块。
- 点击签名选项卡,然后点击添加 。
-
选择您的密钥库文件,输入此签名配置的名称(因为您可能创建多个),然后输入所需的信息。
- 根据需要重复步骤 3 和 4,直到您创建所有签名配置。
- 点击风格选项卡。
- 点击您想要配置的风格,然后从签名配置下拉菜单中选择相应的签名配置。
重复此操作以配置任何其他产品风格。
- 点击确定。
您也可以在 Gradle 配置文件中指定签名设置。有关更多信息,请参阅配置签名设置。
运行签名报告
要获取应用每个变体的签名信息,请在 Android Studio 中运行 Gradle signingReport
任务。
- 选择查看 > 工具窗口 > Gradle 以打开 Gradle 工具窗口。
- 选择您的应用 > 任务 > 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 } } ... }
- 打开构建变体工具窗口,并确保选择了发行版构建类型。
- 选择构建 > 构建 Bundle(s)/APK(s) 下的一个选项来构建发行版构建的 APK 或应用包。您应该在模块的
build/outputs/
目录中看到构建输出。
由于您的构建文件不再包含敏感信息,您现在可以将其包含在源代码管理中或将其上传到共享代码库。请务必保护 keystore.properties
文件的安全。这可能包括将其从您的源代码控制系统中删除。