为什么不能将 keystore 文件提交到 Git 仓库?

解读

在国内 Android 面试中,面试官问“为什么不能把 keystore 提交到 Git”并不是想听你背“安全”两个字,而是考察你对整个应用签名体系、持续集成、合规审计、国内多渠道加固以及可能引发的法律责任的闭环理解。回答时要把“私钥泄露”带来的连锁风险拆成技术、流程、合规、商业四条线,让面试官感受到你不仅懂代码,还懂国内落地环境。

知识点

  1. 签名机制:APK/AAB 的 v1/v2/v3/v4 签名方案中,keystore 里的私钥是生成数字签名的唯一凭证;一旦泄露,任何人可重签名并覆盖安装。
  2. 覆盖安装攻击:国内各大厂商商店、微信/QQ 分享、企业 MDM 都依赖签名做身份校验,签名一致即可静默升级,等于把“应用身份”拱手让人。
  3. 加固与合规:国内上线必须通过腾讯乐固、阿里聚安全、360 加固等,这些服务会二次签名;若原始私钥泄露,加固包也可被伪造,导致监管抽检失败、应用下架。
  4. 法律责任:《网络安全法》第 21 条要求企业采取“数据分类、重要数据备份和加密等措施”,私钥属于关键加密材料,泄露可被认定为“未履行安全保护义务”,最高可处十万元罚款。
  5. CI/CD 隔离:国内主流方案是把 keystore 放在 Jenkins/GitLab CI 的 Secret File、阿里云 KMS、华为云 CodeArts 加密仓库或本地签名机,构建时注入,Git 仓库仅保存加密后的占位符,实现“代码与密钥分离”。
  6. 回滚与追责:Git 历史无法真正擦除,一旦 push 即使后续删除也能被恢复,等于永久留痕;若被员工恶意拉走,公司很难自证“已尽到合理保管义务”。

答案

“keystore 文件里存放的是应用签名的私钥,它在 Android 生态中等同于应用的‘身份证+公章’。如果把 keystore 提交到 Git,就等于把身份证和公章复印后贴在公告栏,风险可以分四层:
第一,技术层:任何人都能用这套私钥重签名 APK,实现‘覆盖安装’攻击,用户无感知就被植入恶意代码;国内商店和系统只认签名不认渠道,伪造包可以直达用户。
第二,流程层:国内上线要走加固、重签名、渠道分包,原始私钥泄露会导致加固包也可被二次伪造,使公司失去版本一致性,回滚和灰度策略全部失效。
第三,合规层:《网络安全法》把密钥列为重要加密材料,泄露即构成‘未履行安全保护义务’,监管抽检可直接下架应用并处以罚款;若伪造包造成用户资金损失,公司还要承担连带民事赔偿。
第四,商业层:Git 历史不可擦除,离职员工或外包人员可随时克隆旧库导出私钥,公司无法证明‘已妥善保管’,在仲裁中处于绝对劣势。
因此国内成熟团队都会把 keystore 放入 CI 加密仓库或硬件签名机,Git 只保留空占位符,实现代码与密钥彻底隔离。”

拓展思考

面试官可能追问:“如果业务必须多人共用签名,怎么在保证安全的前提下协作?”
可以继续答:
“国内常规做法是‘签名机+白名单+审计’三件套:

  1. 用一台内网隔离的 Mac Mini 或华为云签名机作为专用签名服务器,keystore 存进 TEE 或 USB 加密狗,私钥不可导出;
  2. 在 Jenkins/GitLab CI 中配置 job 级权限,仅允许特定受信账号触发签名任务,所有参数通过 KMS 动态注入,构建日志自动脱敏;
  3. 每次签名生成 SBOM(软件物料清单)并写入阿里云 OSS 审计桶,记录 MD5、渠道、时间、操作人,方便后续公安网安大队溯源;
  4. 若出现紧急发布,走‘双人复核+钉钉审批’,签名机需两把 USBKey 同时插入才能解锁,符合《信息安全等级保护 2.0》对‘关键操作多人共管’的要求。
    这样既满足多人协作,又满足国内监管对‘密钥全生命周期可追溯’的强审计要求。”