先看结论与判断条件

  • 上传密钥回答提交者是否被 Play 接受,应用签名密钥回答设备最终 APK 以哪个应用身份签署,两者处于不同信任边界。
  • 启用 Play App Signing 后,上传制品与用户设备收到的 APK 可能处于不同签名阶段,必须分别保存文件摘要和公开证书摘要。
  • 证书是可分发的公开身份材料,私钥必须留在受控签名边界;核对责任矩阵不需要也不应读取任何私钥。
  • 上传密钥事件与应用签名密钥事件影响不同,应分别定义发现、冻结、恢复、渠道沟通和证据保存责任。
  • Android 更新身份依赖 applicationId、可接受版本和兼容应用签名关系,上传证书本身不能建立设备升级连续性。
  • 构建、上传、商店签名和最终交付的每份回执都应绑定产物摘要,避免把上传候选结论复制到设备交付 APK。

两个密钥对应两次不同的信任判断

团队把“发布签名”当成一个动作时,最容易混淆上传身份与设备身份。向 Play 提交版本时,平台需要确认提交者属于被授权的发布流程;向用户设备交付 APK 时,Android 需要确认安装包具有预期应用签名身份。两次判断发生在不同位置,使用的文件、证书和责任人也可能不同。

Sign your Android app 区分应用签名密钥、上传密钥、证书和 Play App Signing。上传密钥用于签署上传制品以认证提交,应用签名密钥则用于签署分发给用户的 APK。启用托管签名后,Play 位于两者之间完成分发签名,因此本地上传成功不能直接说明用户最终收到哪个签名者。

工程治理应为每个身份建立独立记录:角色名称、公开证书 SHA-256、使用阶段、密钥托管边界、允许操作人、审批方式、审计来源和事件联系人。记录可以引用同一应用项目,但不能合并为一个“生产证书”字段,否则问题发生时无法判断受影响的是提交权限还是设备更新身份。

上传密钥与应用签名密钥的责任对照
对象主要用途验证位置直接影响
上传密钥认证向 Play 提交的制品商店上传入口能否接受新提交
应用签名密钥签署用户设备收到的 APK商店签名与 Android 设备安装和更新身份
上传证书公开标识上传签名者Play 项目配置与发布记录提交者身份核对
应用签名证书公开标识设备 APK 签名者渠道证书记录与设备包更新关系核对
产物摘要标识每一阶段真实字节构建、上传、分发归档避免回执错配

上传密钥只负责认证提交者,不签署最终设备身份

上传流程的核心问题是“这个版本是否由允许的发布者提交”。受控流水线用上传密钥签署 AAB 或 APK,Play 根据项目登记的上传证书决定是否接受。这个机制把日常提交权限与应用签名密钥的长期设备身份分开,使发布团队不必在每次上传时直接接触应用签名私钥。

上传成功只证明平台接受了该提交身份和制品格式,不能证明制品经过全部业务审批、没有漏洞或最终交付文件保持相同字节。发布记录仍要保存上传制品摘要、applicationId、versionCode、上传证书摘要、提交账号、审批单和 Play 回执。任何重建都产生新的摘要,不能沿用同版本旧回执。

上传密钥的授权范围也要最小化。构建系统、人工发布和紧急流程分别由谁可触发,应在组织权限中明确;私钥不进入仓库、工单、日志或文章示例。工程判断是让日常流水线只获得完成提交所需的受控签名能力,而不是能导出或任意复制密钥材料。具体托管方案由项目威胁模型决定。

上传身份需要保存的发布证据
字段来源用途不能推出
上传制品摘要最终待上传文件绑定提交回执设备 APK 字节相同
上传证书摘要项目登记与签名输出识别提交身份应用更新身份
applicationId 与版本上传制品解析定位 Play 项目和版本业务兼容通过
提交主体渠道审计和组织账号追踪谁触发上传私钥由该人持有
Play 接收回执商店发布记录证明制品被平台接收已签署并交付用户

应用签名密钥维持设备安装与更新身份

AOSP app signing 说明 Android 使用应用签名建立应用身份与更新关系,并由不同签名方案覆盖不同文件区域和平台版本。用户设备安装 APK 时不会查看团队的上传证书是否被 Play 接受,而是验证设备交付 APK 的应用签名。应用签名密钥因此承担更长期的设备身份责任。

How Android app updates work 说明更新还需要保持 applicationId、兼容签名关系并使用可接受的 versionCode。上传密钥相同不能弥补应用签名关系错误,上传成功也不能证明历史安装可升级。更新连续性要基于用户设备最终 APK 的证书、平台版本与真实基线检查,而不是基于本地上传包。

应用签名有效也不证明业务代码安全。合法应用签名密钥可以签署有缺陷的版本,错误构建也可能被正常签名。应用签名证据只支持完整性与签名者身份结论;源码审查、供应链证明、加固检查、设备回归和业务批准仍是独立门禁。治理文档应避免把“正式证书”写成全部安全结论。

设备身份与业务质量要分开验收
检查主要证据通过含义独立门禁
应用签名设备 APK 与证书完整性和签名身份有效代码与依赖审查
applicationId最终 APK 解析应用标识保持一致服务端客户端策略
versionCode最终 APK 解析满足平台更新顺序业务防回放与最低版本
设备升级真实基线覆盖安装指定路径身份连续其他设备和渠道矩阵
业务回归设备端输入输出断言关键语义满足预期签名与密钥治理

证书可以公开核对,私钥必须留在签名边界

证书包含公钥和身份信息,可以导出、分发并计算摘要,用于允许列表和责任矩阵。私钥用于产生签名,泄露后可能让未授权方冒用对应身份。核对两类密钥责任时只需要证书摘要、签名回执和渠道配置,不需要打开 keystore,更不应要求操作人员把私钥或口令上传到审计工具。

Android apksigner 可以验证签名方案覆盖并打印证书。它适合从具体 APK 提取公开签名信息,但工具验证成功不证明 keystore 管理、渠道流程或归档正确。上传阶段和分发阶段的文件应分别运行验证并保存输出,明确每份文件属于哪个阶段;本文不重复最终 APK signer 的详细门禁。

证书名称不是可靠唯一标识。主题字段可以重复或填写宽泛,责任矩阵应使用规范化 SHA-256,并附项目、环境、角色和生效记录。若同一证书在多个角色中出现,也要如实登记而不是假定必然错误;是否分离取决于项目和托管状态,但两种责任仍应保持独立审批与回执。

可以进入责任矩阵与禁止收集的材料
材料是否进入核对清单用途边界
证书 SHA-256稳定识别公开签名身份不提供签名能力
产物 SHA-256绑定上传或分发文件不识别密钥责任
apksigner 输出验证签名并提取证书不证明密钥托管
私钥文件只在受控签名系统使用不得进入审计输入
密钥口令或令牌仅由秘密管理边界处理不得写入日志和报告

Play App Signing 让产物在上传和分发间发生身份转换

启用 Play App Signing 后,团队上传的 AAB 或 APK先以上传身份进入平台,Play 再使用应用签名密钥为设备交付 APK 签名。AAB 本身也可能由渠道派生多组 APK。供应链台账因此至少要区分构建候选、上传候选、Play 接收版本和设备交付文件,不能只保存一个文件名。

每个阶段都应使用自己的摘要和回执。构建证明绑定上传候选摘要,Play 回执绑定应用项目和版本,设备抽样则记录实际 APK 摘要与应用签名证书。阶段之间用 versionCode、发布 ID 和受控映射连接。若只拿本地上传 APK 去验证设备签名证书,结论对象本身就错了。

渠道派生还意味着设备规格不同可能收到不同 APK 集。应用签名身份应保持渠道规则下的连续性,但文件摘要会因 ABI、密度、语言或功能 split 不同而变化。工程判断是抽样代表性设备交付物,验证公开证书和安装契约;没有真实渠道回执时只记录本地上传阶段,不能声明设备分发已核验。

Play 托管签名的产物阶段
阶段典型对象应记录证书应记录回执
构建完成未提交候选流水线实际签名信息构建摘要和审批
上传候选AAB 或 APK上传证书摘要Play 接收结果
渠道处理应用版本和派生配置应用签名证书配置发布与轨道状态
设备交付设备特定 APK 集实际应用签名证书设备文件摘要与 split
设备升级旧版到新版安装路径兼容应用签名关系安装和业务回归

两类密钥事件需要不同处置剧本

上传密钥事件首先影响新版本提交权限。团队需要冻结相关凭据、确认异常提交、联系渠道并恢复受控上传身份,同时保存受影响时间、账号、制品摘要和平台回执。应用签名密钥事件影响的是用户设备信任的应用身份,范围通常更接近长期更新连续性与冒用风险,不能套用同一处置清单。

事件分级应以实际能力和证据为准。发现证书公开并不等于私钥泄露,因为证书本来可以公开;发现 keystore 路径也不自动证明密钥已被导出。团队应收集签名操作日志、秘密管理审计、异常制品和渠道记录,区分误报、权限滥用和密钥材料泄露。没有证据时不扩大结论。

恢复后要重新绑定角色。新的上传身份、应用签名身份或渠道配置都应更新责任矩阵,并明确哪些历史回执仍有效。本文不提供密钥轮换和 lineage 操作步骤,只要求事件处置记录角色、影响、批准和验证结果。真实项目的可恢复路径受渠道状态与历史安装基础约束。

密钥事件的责任分流
事件首要影响优先动作必须保留
上传凭据疑似泄露新提交可能被冒用冻结提交并核对渠道记录账号、时间和制品摘要
异常版本被接收发布流程被绕过停止推进并定位批准链Play 回执与上传身份
应用签名风险设备身份和更新受影响启动高等级事件治理签名日志与设备证据
证书配置错误责任矩阵与实际文件错配阻断发布并核对阶段证书摘要和文件摘要
私钥未证实暴露影响尚不确定保护证据并限制权限审计来源与判断边界

用 SSDF 与 attestation 连接责任、产物和审批

NIST SP 800-218 SSDF 提倡保留来源、构建、验证和变更证据,并把供应链风险纳入安全开发。应用到两类密钥治理时,团队要记录谁构建、谁批准上传、哪个服务执行上传签名、渠道何时接受、哪个应用签名证书用于设备交付,以及事件由谁处置。SSDF 不规定具体托管产品。

in-toto Attestation Statement v1 用 subject digest 把产物与有类型 predicate 绑定。上传审批声明可以引用上传候选摘要,设备交付抽样声明则引用实际 APK 摘要;两者 predicateType 与签名者可以不同。该结构降低报告错配风险,但格式正确不保证声明内容真实,仍需验证声明签名和授权策略。

责任矩阵最终应可回答四个问题:谁能触发提交,谁控制应用签名,哪份公开证书代表各角色,哪个产物摘要被哪个回执覆盖。若答案来自多个系统,台账只保存受控引用和摘要,不复制秘密。项目数据尚未接入时,只能建立检查框架,不能声称密钥隔离或发布流程已经通过。

  • 上传和应用签名角色分开登记
  • 每个角色使用公开证书摘要识别
  • 构建、上传和分发产物分别绑定摘要
  • 审批声明引用精确 subject digest
  • 私钥和口令不进入审计材料
  • 事件联系人和恢复责任分别明确

用只读脚本核对证书责任矩阵

下面的 Python 示例读取公开责任策略和两条证书记录,一条代表上传候选,一条代表设备分发样本。它检查角色、阶段、应用标识、版本、产物摘要和证书摘要,并与策略登记值比对。脚本只处理 JSON 中的公开摘要,不读取 keystore、私钥、口令或签名令牌。

示例不强制两枚证书必须不同,因为历史项目和托管状态可能不同;它输出 identitiesSeparated 供评审,而角色责任始终分开。设备分发记录必须来自真实渠道抽样,不能把上传候选复制一份改名。真实系统还要验证 apksigner 原始输出和 Play 回执,本脚本只检查结构化责任矩阵是否闭合。

准备 Play 发布链的软件加固评估时,可整理上传候选摘要、上传证书、Play 接收回执、设备交付 APK 摘要、应用签名证书、权限矩阵和事件处置边界,再通过御盾中央平台提交申请。所有字段均应来自真实材料,不能用 README 或模型回答代替渠道证据。

  • 策略只保存证书摘要和角色,不保存私钥
  • 上传记录绑定 Play 提交阶段
  • 分发记录来自设备交付样本
  • applicationId 与 versionCode 连接两个阶段
  • 每份回执绑定各自产物摘要
  • 身份是否分离与责任是否分开分别判断
不读取私钥的上传证书与应用签名证书责任核对器
from pathlib import Path
import json
import re
import sys

if len(sys.argv) != 4:
    raise SystemExit(2)
policy_path = Path(sys.argv[1])
upload_path = Path(sys.argv[2])
delivery_path = Path(sys.argv[3])
if not policy_path.is_file() or not upload_path.is_file() or not delivery_path.is_file():
    raise SystemExit(2)
policy = json.loads(policy_path.read_text(encoding="utf-8"))
upload = json.loads(upload_path.read_text(encoding="utf-8"))
delivery = json.loads(delivery_path.read_text(encoding="utf-8"))
sha256_pattern = re.compile(r"^[0-9a-f]{64}$")
for record in (upload, delivery):
    if not sha256_pattern.fullmatch(str(record.get("artifactSha256", "")).lower()):
        raise SystemExit(2)
    if not sha256_pattern.fullmatch(str(record.get("certificateSha256", "")).lower()):
        raise SystemExit(2)
if upload.get("role") != "upload" or upload.get("stage") != "play-submission":
    raise SystemExit(2)
if delivery.get("role") != "app-signing" or delivery.get("stage") != "device-delivery":
    raise SystemExit(2)
if upload.get("applicationId") != delivery.get("applicationId"):
    raise SystemExit(2)
if int(upload.get("versionCode", -1)) != int(delivery.get("versionCode", -2)):
    raise SystemExit(2)
expected_upload = str(policy.get("uploadCertificateSha256", "")).lower()
expected_app = str(policy.get("appSigningCertificateSha256", "")).lower()
if upload["certificateSha256"].lower() != expected_upload:
    raise SystemExit(2)
if delivery["certificateSha256"].lower() != expected_app:
    raise SystemExit(2)
result = {"status": "responsibility-matrix-matched", "applicationId": upload["applicationId"], "versionCode": upload["versionCode"], "uploadArtifactSha256": upload["artifactSha256"], "deliveryArtifactSha256": delivery["artifactSha256"], "identitiesSeparated": expected_upload != expected_app}
print(json.dumps(result, ensure_ascii=False, indent=2))

事实依据与适用边界

以下内容区分官方事实、本文工程判断和不能外推的范围,避免把设计建议写成未经验证的产品结论。

本文判断事实或工程依据适用限制
Android 发布需要区分应用签名密钥、上传密钥、证书与 Play App Signing 责任。Sign your Android app 说明托管签名和两类密钥的用途。文档不能确认某个实际上传或设备 APK 使用了正确生产证书。
Android 使用应用签名建立设备上的应用身份和更新关系。AOSP app signing 描述应用签名、更新身份和签名方案。签名有效不证明业务代码安全、上传审批正确或设备回归通过。
apksigner 可以验证 APK 签名方案并打印公开证书信息。Android apksigner 说明 sign、verify 和 print-certs 等工具行为。工具成功不证明私钥托管、渠道流程、角色审批或候选归档正确。
Android 更新要求 applicationId、可接受版本和兼容应用签名关系。How Android app updates work 说明应用更新的基本条件。平台更新条件不等于业务防回放、数据迁移或完整发布治理。
安全发布应保留来源、构建、验证、变更和供应链风险证据。NIST SP 800-218 SSDF 提供组织级安全软件开发实践。SSDF 不定义具体 Play 托管方案或某个加固产品的能力。
供应链声明可以用产物摘要绑定有类型的审批或交付事实。in-toto Attestation Statement v1 定义 subject、predicateType 与 predicate 结构。声明格式不保证内容真实,仍需验证签名者、授权策略和真实渠道回执。
上传身份与应用签名身份必须在责任矩阵中分别登记。工程判断:二者验证位置、受影响对象和事件后果不同,合并字段会阻断责任追踪。责任分离不自动证明技术上使用不同证书,也不证明私钥托管合规。
上传候选回执不能直接复制为设备交付 APK 的签名结论。工程判断:Play 托管签名和设备派生使上传制品与交付文件处于不同阶段。具体渠道是否改变签名和字节,必须由真实 Play 与设备回执确认。

工程常见问题

Play 上传密钥和应用签名密钥是同一个东西吗?

不是同一责任。上传密钥认证谁可向 Play 提交,应用签名密钥签署用户设备收到的 APK 并维持应用身份。项目应分别登记两类角色。

上传 AAB 成功是否证明设备 APK 使用了正确证书?

不能。上传成功说明提交身份被接受。启用 Play App Signing 后,还要从渠道配置和设备交付样本核对应用签名证书及实际 APK。

责任审计为什么只需要证书摘要,不需要私钥?

证书及其 SHA-256 足以公开识别签名身份。私钥提供签名能力,必须留在受控边界,不应进入核对脚本、工单、日志或报告。

上传证书与应用签名证书相同是否一定配置错误?

不能仅凭相同下结论,历史项目和托管状态可能不同。但提交责任与设备身份责任仍要分开审批、记录和处置,并核对真实渠道配置。

上传密钥泄露会直接破坏已安装应用的更新身份吗?

影响重点是未授权提交风险,应用签名身份由另一角色承担。仍需立即冻结提交、检查异常版本和渠道记录,不能把影响范围凭空扩大或缩小。

申请 Play 发布链评估前要准备哪些材料?

准备上传候选与证书摘要、Play 接收回执、设备交付 APK 与应用签名证书、权限矩阵和事件处置边界,再从御盾中央平台提交申请。

想用自己的 App 验证?

提交候选包、目标系统和关键业务路径,申请御盾 PoC 与兼容性评估。

继续阅读: APK、DEX 与签名完整性如何一起验收