跳到主要内容

安全与密钥

移动端安全不是「加个 ProGuard 就结束」。参考工程把 日志、Token、备份、一次性 secret 写成可检查的约定。

日志策略

构建类型网络日志其它
DebugOkHttp 可为 BASIC可有高层诊断
ReleaseHttpLoggingInterceptor.Level.NONE不打 URL/头/体/Token

AppLogger 会脱敏常见 token/secret 模式;release 下不附加 throwable 细节。

禁止出现在 release 日志中的内容(示例):

  • access / refresh token
  • admin token
  • 设备 secret、bootstrap token
  • 邀请、邮箱验证、密码重置等 dev token
  • 完整请求/响应体中的敏感字段

Token 处理

数据存储使用
Access / RefreshDataStore only拦截器与登出/刷新
Admin tokenDataStore only/internal/admin/*X-Admin-Token
进程内 access 快照内存避免每个请求都读 DataStore

要点:

  • Token 不进 Room
  • 诊断页只显示 admin token 是否已配置,不显示值
  • Refresh 单飞:并发 401 只触发一次刷新
  • Refresh 失败 → 清空会话

备份与导出

  • AndroidManifestandroid:allowBackup="false"(以仓库为准)
  • 备份 / 数据提取 XML 排除 files/datastore/
  • 避免会话与 admin token 被系统备份到云端再恢复到别的设备

一次性设备 Secret

创建设备等接口可能返回 仅显示一次 的 secret:

  • 只放在 ViewModel / UI 状态
  • 一次性对话框展示并可复制
  • 关闭对话框或离开路由后清除
  • 不写 Room、不进普通列表缓存

验收:离开详情再回来,不应再次看到同一 secret。

Room 缓存审计原则

缓存表可以存业务标识(如 keyId),但:

  • 不存 access/refresh/admin token
  • 不存 device secret / bootstrap token
  • 不把「仅一次」的凭证持久化成「永远可查」

改 Entity 时做一次敏感字段扫视。

错误信息展示

字段用途
ErrorResponse.error.message普通 UI 可展示
code / details诊断、debug、Admin;不要默认弹给最终用户

发布前安全核对(摘要)

  • Release 网络日志为 NONE
  • R8 / 优化按工程配置开启(AGP 9 gradual R8 等以 gradle.properties 为准)
  • 无 keystore、签名密码进 Git
  • 端点默认仍是团队约定环境;本地 override 仅 opt-in
  • 备份关闭 / DataStore 排除
  • 一次性 secret 路径人工点过一遍

完整条目见仓库 docs/SECURITY_NOTES.mddocs/RELEASE_CHECKLIST.md

下一步:构建与发布