3. 原始应用签名密钥的生成与保管

本章聚焦Android应用签名的起点——使用JDK内置的keytool工具生成JKS格式密钥库,并建立从密钥创建、密码与别名记录到离线备份的完整保管流程。密钥是应用数字身份的根,一旦丢失或泄露,将导致无法更新已发布应用、无法通过Google Play Integrity验证,甚至被恶意篡改冒签。本章按SOP流程逐一拆解每个操作节点。

JKS密钥生成与离线备份流程 安装JDK 确认 keytool 可用 生成JKS密钥库 -genkey -keyalg RSA 记录密钥凭证 密码、别名、指纹 加密打包 AES-256 + 密码信封 离线介质写入 USB / 刻录光盘 物理隔离存储 保险柜 / 银行保管箱 验证恢复测试 从备份介质还原签名 定期轮换与审计 年度密钥可用性检查 ⚠ 密钥在线存储时间 ≤ 10 分钟;生成后立即执行离线备份,清除临时文件 备份介质至少2份异址存放,每份独立加密

适用场景

  • 新应用首次发布:为应用创建独立的原始签名身份,用于Google Play App Signing初始上传密钥。
  • 密钥轮换或补签:需要为已有应用生成新的签名密钥,并替换Google Play控制台中的上传密钥。
  • 企业级多应用隔离:每个应用或应用组使用独立JKS密钥库,防止单点泄露波及全系产品。
  • 合规审计要求:金融、政务、医疗类应用需满足密钥生成和保管的可追溯、可恢复标准。

前置条件

条件项要求确认方式
JDK 版本≥ JDK 8(推荐 JDK 11 LTS 或 JDK 17 LTS)java -version
keytool 可用位于 $PATH 或 %JAVA_HOME%\bin\keytool -help
操作系统macOS / Linux / Windows 均可,无特殊限制—
离线存储介质≥ 2 份独立物理介质(USB 加密盘 / 刻录光盘 / 硬件密码模块)物理检查 + 写入测试
密码管理工具企业密码管理器(如 1Password、KeePass、Bitwarden)或纸质密封信封记录完整性检查

操作步骤

Step 1:确认工作目录与环境变量

  1. 创建一个专用工作目录(例如 ~/app-signing-keys/ 或 D:\signing-keys\),该目录仅用于本次密钥生成,生成后清理。
  2. 打开终端(macOS/Linux)或命令提示符(Windows 以管理员身份运行)。
  3. 验证 keytool 可执行:
keytool -genkey -v -keystore my-release-key.jks \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias my-app-key-alias
最佳实践:-validity 建议 ≥ 10000 天(约 27 年),覆盖应用完整生命周期。Google Play 要求上传密钥的有效期超过应用预期寿命,避免中途过期导致签名验证失败。

Step 2:交互式填写密钥信息

执行上述命令后,keytool 会依次提示以下字段。请逐项填写,所有字段必须真实、完整,不可使用占位符:

提示字段填写指导示例
Keystore 密码≥ 16 位,混合大小写 + 数字 + 特殊字符;立即记录Jks!P@ss2024#Sec
密钥密码建议与 Keystore 密码一致(回车确认),也可独立设置同上或独立强密码
名字与姓氏填写组织负责人或应用发布者真实姓名Zhang Wei
组织单位 (OU)填写部门名称,如移动开发部Mobile Engineering
组织 (O)填写公司法定全称Example Tech Co., Ltd.
城市/地区 (L)填写注册城市Beijing
州/省 (ST)填写注册省份Beijing
国家代码 (C)两位 ISO 国家代码CN
风险警示:密钥密码与别名是恢复签名的唯一凭证。密码丢失将导致整个密钥库不可用,应用永远无法发布更新。密码生成后必须立即使用密码管理器保存,并打印纸质副本密封存档。

Step 3:确认密钥库文件与指纹

  1. 生成完成后,当前目录出现 my-release-key.jks 文件。
  2. 使用以下命令查看密钥指纹(SHA-256),并与 Google Play 控制台要求的指纹格式比对:
keytool -list -v -keystore my-release-key.jks -alias my-app-key-alias

输出中重点关注 SHA-256 和 有效期至 字段。示例输出片段:

Alias name: my-app-key-alias
Creation date: 2025-01-15
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Zhang Wei, OU=Mobile Engineering, O=Example Tech Co., Ltd., L=Beijing, ST=Beijing, C=CN
Issuer: CN=Zhang Wei, OU=Mobile Engineering, O=Example Tech Co., Ltd., L=Beijing, ST=Beijing, C=CN
Serial number: 1a2b3c4d
Valid from: Wed Jan 15 10:30:00 CST 2025 until: Sun Jun 02 10:30:00 CST 2052
Certificate fingerprints:
  SHA-256: AB:CD:EF:01:23:45:67:89:AB:CD:EF:01:23:45:67:89:AB:CD:EF:01:23:45:67:89:AB:CD:EF:01:23:45:67:89
  SHA-1:   FE:DC:BA:98:76:54:32:10:FE:DC:BA:98:76:54:32:10

Step 4:记录密钥凭证与元数据

填写《密钥凭证记录表》(参见记录材料章节),必须包含以下信息:

  • 密钥别名:my-app-key-alias
  • Keystore 密码:记录在密码管理器 + 纸质密封信封
  • 密钥密码:同上
  • SHA-256 指纹:完整 64 位十六进制字符串
  • 有效期截止日期:如 2052-06-02
  • 生成时间与操作人:精确到分钟,记录执行者姓名
双重记录原则:电子记录(密码管理器)+ 纸质记录(防火防潮密封袋)分开存放,确保任何单一灾难不会同时摧毁两份记录。

Step 5:加密打包与离线备份

  1. 将 my-release-key.jks 和《密钥凭证记录表》放入一个加密 ZIP 包:
# 使用 GPG 对称加密(推荐 AES-256)
gpg --symmetric --cipher-algo AES256 --output signing-key.gpg my-release-key.jks

# 或者使用 7-Zip 加密 ZIP(AES-256)
7z a -tzip -p"YourBackupPassword" -mem=AES256 signing-key-backup.zip my-release-key.jks record-sheet.pdf
  1. 将加密包写入 至少 2 份 物理介质:USB 加密盘 + 一次性写入光盘(DVD-R / BD-R)。
  2. 在介质表面粘贴标签(仅写项目编号和日期,不写“签名密钥”等敏感词)。
  3. 将介质存入不同的物理隔离位置:公司保险柜 + 银行保管箱 或 异地灾备中心。
安全红线:密钥库文件严禁以明文形式存储在 GitHub、GitLab、云盘、CI/CD 环境变量、Docker 镜像或任何联网位置。加密包也不应上传至云存储,除非使用企业级 HSM 或 KMS 服务配合访问审计。

Step 6:清理工作痕迹

  1. 确认备份介质写入成功并验证可读取后,立即删除工作目录下的 my-release-key.jks 明文文件。
  2. 清空终端历史记录(macOS/Linux: history -c;Windows: doskey /listsize=0)。
  3. 重启终端窗口,确保密码不残留在 shell 历史或环境变量中。

输入输出物

类别输入物输出物保管要求
密钥文件—my-release-key.jks(加密后归档)离线 + 加密 + 异址
凭证记录—《密钥凭证记录表》(电子+纸质)密码管理器 + 密封信封
备份介质空白 USB / 空白光盘写入加密包的物理介质 × 2+双份异址物理隔离
指纹信息—SHA-256 指纹摘要存入 Google Play 控制台 + 本地记录
环境记录JDK 安装包生成日志(脱敏后)审计归档 3 年

责任边界

  • 开发工程师:执行 keytool 命令、填写交互信息、确认指纹正确性。不得私自留存密钥副本或密码。
  • 安全官 / 密钥管理员:监督生成过程、审核凭证记录、执行加密打包并护送备份介质至离线存储位置。拥有密码纸质的唯一访问权。
  • QA / 审计员:验证备份介质可恢复性(不接触明文密码)、检查清理痕迹、记录审计日志。
  • CI/CD 管理员:仅在收到经安全官签发的加密密钥包后,方可将其导入构建系统的加密存储区(如 Jenkins Credential Binding 或 GitLab CI/CD Masked Variables)。

记录材料

以下记录表需在本章操作完成后 24 小时内填写完毕,由安全官签字归档:

记录项内容存放位置
《密钥生成操作记录表》生成时间、操作人、环境信息、密钥参数、指纹摘要内部审计系统 + 纸质归档
《密钥凭证记录表》别名、Keystore 密码、密钥密码、有效期、SHA-256密码管理器 + 纸质密封信封
《备份介质交接单》介质编号、加密算法、存储位置、保管人、交接时间安全部门档案柜
《恢复测试报告》测试日期、测试人、是否成功还原、签名验证结果归档至应用发布档案

异常处理

异常场景处理措施预防策略
keytool 命令未找到检查 JAVA_HOME 环境变量,重新安装 JDK 或将 bin/ 目录加入 PATH生成前执行 keytool -help 验证
密码输入错误 / 忘记密码立即中止操作,从密码管理器或纸质信封恢复密码;若无法恢复则重新生成密钥并更新 Google Play 上传密钥生成时双人确认 + 立即记录
备份介质写入失败更换介质品牌或类型(如 USB 写入失败改用光盘),重试加密写入步骤准备 ≥ 3 份空白介质备用
指纹与预期不匹配核对命令参数是否正确(别名、密码、算法),重新生成并对比两次指纹生成后立即截图保存,双人复核
密钥文件在加密前被误删若未备份则只能重新生成;若已部分备份则从备份中恢复并补全记录加密前锁定文件只读权限
离线介质物理损坏使用备用介质恢复;若无备用则从另一异址副本拷贝,重新写入新介质坚持“2+1”策略:2份异址 + 1份本地临时副本(加密)

验收标准

  1. 密钥完整性:从任意一份备份介质中完整还原 .jks 文件,使用 keytool -list -v 查看指纹与原始记录表完全一致。
  2. 密码可恢复:从密码管理器或纸质密封信封中提取的密码可以成功打开密钥库,且别名匹配。
  3. 备份冗余:至少 2 份独立物理介质已存入不同物理位置(公司保险柜 + 银行保管箱或异地灾备中心),交接单签字完整。
  4. 痕迹清除:工作目录下无明文 .jks 文件残留,终端历史记录已清空,无敏感信息泄露风险。
  5. 文档归档:所有记录表(操作记录、凭证记录、交接单、恢复测试报告)已填写并签字,电子版存入审计系统,纸质版存入档案柜。
  6. Google Play 关联:生成的 SHA-256 指纹已成功上传至 Google Play 控制台 > 应用签名 > 上传密钥证书(如适用),且状态为“已启用”。
验收通过标志:以上 6 项全部为“是”后,由安全官在《密钥生成操作记录表》中签署“验收通过”并加盖部门章,本章流程方可关闭。