Google Play 应用的密钥管理与 API Key 保护
1. 真正要回答的问题只有一个:哪些 Key 本来就允许出现在安装包里。Google 自己的 Android 安全指南把话说得很直——这不是混淆能解决的问题:「当应用被编译、源码中包含 API Key 时,攻击者可以反编译应用并找到这些资源。」所以 APK 里的每一个字符串、每一个被打包的资源或 asset,都应当视为已公开。客户端 Key 只允许是低权限、有配额上限、作用域受限的那一类:地图、天气、只读内容流、公开搜索。凡是可以动钱、可以读别人记录、可以退款、可以发信、可以改服务端状态的,一律不能放进客户端,必须放在你自己的服务端接口后面,并由服务端识别用户身份。(§https://developer.android.com/privacy-and-security/security-tips)
2. Play 的用户数据政策通篇没有出现「API Key」这个词,它管的是结果——这也是为什么 Key 泄露不只是工程问题,而是政策问题。政策要求开发者「安全地处理所有个人与敏感用户数据,包括使用现代加密方式传输(例如通过 HTTPS)」,并要求「以适当的安全措施保护所有用户数据,包括对传输中的数据使用现代加密」。硬编码 Key 本身不构成违规;但这个 Key 让攻击者能读取、写入或外带用户数据时,就已经是用户数据政策违规,除账单与数据泄露通知之外,还叠加下架风险。§https://support.google.com/googleplay/android-developer/answer/10144311
3. Key 限制不是身份认证,Google Cloud 文档自己就写明:「标准 API Key 不认证任何主体(principal)」,它的作用是把这个请求关联到一个项目上,用于计费与配额。应用限制(网站、IP、Android 应用、iOS 应用,一次只能选一种)与 API 限制只是止损,不是保密;而且 Android 应用限制自带一条明文提示:「绕过该限制非常容易。如果你使用了这一限制,还应同时加上 API 限制并监控用量。」同一文档的建议是 API 限制与应用限制两者都设,然后再看这个 Key 实际被调用了什么。§https://cloud.google.com/docs/authentication/api-keys
4. 真正起作用的是这份卫生清单。绝不把 Key 提交进仓库——Android 官方指南给的做法是用 secrets-gradle-plugin 这类 Gradle 插件,而不是把 Key 写进被跟踪的文件。开发、测试、生产各用独立的 Key,每个应用也用独立的 Key,这样某个 Key 被泄露时可以单独停用而不拖垮生产。调用方是服务器时用 IP 限制。确实必须留在设备上的秘密(令牌、刷新材料)要放进 Android Keystore,并用经过审查的库(如 Tink)加密,而不是字符串常量、asset 文件或明文 SharedPreferences。全程 HTTPS,证书固定(certificate pinning)只能作为额外一层,不能当作替代品。§https://developer.android.com/privacy-and-security/security-tips
5. 轮换是日历上的固定项,不是出事才想起来的反射动作。Android 指南引用 ISO 27001 并明确写道:「大多数情况下,90 天到 6 个月的 Key 轮换周期是足够的」;Google Cloud 的轮换操作会生成一个限制相同的新 Key,旧 Key 在你删除之前一直有效。这段重叠窗口才是关键:已经在用户手机上的安装要按周甚至按月才更新完,所以必须留出「新旧两把 Key 同时有效」的迁移期,然后停用、再删除。维护一份 Key 台账(Key ID、负责人、所属包名、作用域、轮换日期)——单个项目最多 300 个 Key,足够多到让你彻底失去线索。§https://cloud.google.com/docs/authentication/api-keys
6. 检测能力决定这次泄露是一天的事还是一个季度的事。打开按 Key 维度的用量日志与配额/账单告警,盯住三种形状:来自意外 referrer 或 IP 的用量尖峰、在你自己用户都睡着的时段配额被打满、以及调用了应用根本不会调的接口。确认泄露后按固定顺序处理:先建限制完全相同的新 Key,发版让客户端切过去,看旧 Key 流量掉下来,再吊销旧 Key,最后把整个暴露窗口的访问日志与账单过一遍。还要回头核对 Play Console 的 Data safety 声明是否仍与事实一致——「传输中加密」是对真实运行时行为的声明,一个把链路降级成明文的泄露 Key 会让这条声明变成假话。§https://cloud.google.com/docs/authentication/api-keys