【技术深度】金融 / 钱包级 Android 安全性架构(毒APP)

【技术深度】金融 / 钱包级 Android 安全性架构(毒APP)

作者:ZFJ_张福杰

博客:https://zfj1128.blog.csdn.net

日期:2025-12-17

关键词:Android、安全、签名证书


前言

今天我们交易所有个用户反馈自己的952.00U资金被盗了,然后找到我们的客服,当然他资金被盗与我们交易所无关...

查询了他的账号登录记录,一直在他的安卓机上没有改变,不存在账号被盗的情况,然后我就在想,可能的原因:

  1. 用户手机被黑了,被远程控制了;
  2. 身边的人知道他的锁屏密码了,操作了他的手机(用户没有设置2fa,只有邮箱验证码);
  3. 用户自己转错币了(包括粘贴板被黑),来闹,想得到补偿;
  4. 下载的APP不是官方的APP,APP被藏毒了;

然后我想基于第四点【下载的APP不是官方的APP,APP被藏毒了;】,想来聊一聊如何去做攻防,这里不是官方APP又分为两点:

  1. 签名证书(keystore)泄露,得到了重新打包的APP;
  2. APP被反编译,重新签名了,不是原来的bid了;

需要说明的是, 一旦签名证书(keystore)泄露,Android 原生层面已经"无法 100% 阻止"被二次打包的 App 安装。

但可以做到的是:

  • 让被篡改 / 非官方 App "无法正常使用核心功能"
  • 在运行期"精准识别并封禁"非官方 App
  • 让攻击成本远高于收益(工业级防护)

也就是说: 你阻止不了用户"安装",但你可以阻止它"活着"。


一、总体安全目标

1、钱包 / 金融 App 的核心安全目标:

不信任客户端,不信任系统,不信任安装来源。

2、整体架构鸟瞰:

Integrity Gateway 是金融 App 的"门神"。

二、签名泄露

1、为什么不能彻底阻止安卓?

Android 的签名机制本质,校验的是:

  • APK 内的 签名是否自洽
  • 不是校验「是不是你官方发的」

如果 攻击者拿到了你的签名证书

  • 他重新打包
  • 用你的证书重新签名
  • 系统层面 = 合法 App

Android 系统不会知道这是"假官方",签名证书也很容易泄露的,比如公司人员离职。

2、可行的防护思路(核心)

你的目标不是「阻止安装」,而是:

只允许"官方构建链 + 官方环境 + 官方完整性"的 App 运行

3、整体思路:


三、第一道防线:App 自身完整性校验(本地)

1、签名指纹校验(基础但必须)

防止最低级二次打包

在运行时校验:

  • Signing Certificate SHA-256
  • 对比硬编码的官方指纹
java 复制代码
PackageInfo pkgInfo = getPackageManager()
        .getPackageInfo(getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES);

Signature[] signatures = pkgInfo.signingInfo.getApkContentsSigners();
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(signatures[0].toByteArray());

⚠️ 注意

如果证书已经泄露,这一层 会被绕,但仍然是第一道门槛。

2、APK 文件完整性校验(Hash)

  • 运行时计算 APK hash
  • 对比 官方版本 hash 列表
text 复制代码
官方版本 → server → 下发 hash 白名单

⚠️ 攻击者如果 修改代码后再签名,hash 一定变化。


3、Dex / SO 自校验(高级)

  • 对关键 dex / so 做 hash
  • 校验运行内存中的映射文件

常见校验点:

  • classes.dex
  • 核心 so(加壳后更佳)

4、运行环境检测

任何一个异常 → 风险标记

  • Root 检测(最高优先级)
  • Emulator 检测(反自动化)
  • Frida / Xposed 检测(动态注入)
  • Debuggable 检测(防调试)
  • Hook Framework(通用框架)

四、第二道防线:Google 官方完整性证明(强烈推荐)

1、Play Integrity API(非常关键

这是目前 唯一系统级可信方案

2、它能告诉你:

  • ✅是否来自 Google Play
  • ✅是否是 官方签名
  • ✅是否被 篡改 / 重打包
  • ✅是否运行在 Root / Emulator

3、返回核心字段:

json 复制代码
{
  "appIntegrity": {
    "appRecognitionVerdict": "PLAY_RECOGNIZED"
  },
  "deviceIntegrity": {
    "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"]
  }
}

4、你可以做什么?

  • ❌ 非 PLAY_RECOGNIZED直接禁用
  • ❌ 被二次打包 → 拒绝登录 / 核心功能

相关策略:

Verdict 行为
PLAY_RECOGNIZED + STRONG 正常
PLAY_RECOGNIZED + BASIC 限额
UNRECOGNIZED 禁止核心功能

⚠️ 即便攻击者有你的证书:

Play Integrity 仍然能识别"非官方发布链"


五、第三道防线:服务端 Integrity Gateway裁决(最重要)

客户端永远只负责"提交证据",裁决权在服务器

1、启动即做远程认证

复制代码
App 启动
  ↓
生成设备指纹 + 完整性报告
  ↓
服务器验证
  ↓
返回「是否允许使用」

校验维度:

项目 是否可信
签名指纹
APK Hash
Play Integrity 极高
设备指纹
行为特征

2、Token 绑定 App 完整性

  • 登录 token = 绑定

    • App 版本
    • 签名
    • Integrity 结果

篡改 App 即 token 失效。


六、第四道防线:身份 & Token 绑定(防重打包)

Token 不是"登录凭证",而是"设备+App 凭证"

Token 绑定:

  • App Signature
  • APK Hash
  • Integrity Verdict
  • Device Fingerprint
java 复制代码
token = HMAC(user + app + device + integrity)

任一变化 → token 失效


七、终极方案(你问的"不是官方就禁止")

真正可落地的方案是:

只允许「Play Store 官方渠道 + Integrity 通过」的 App 使用

策略示例:
java 复制代码
条件满足:
- Play Integrity = PASS
- APK hash ∈ 官方列表
- 服务端 token 校验通过

否则:
- 禁止登录
- 禁止交易
- 强制升级 / 提示风险

八、我想说

1、现实世界的边界

我们无法阻止安装非官方 App 使用,也无法绝对防破解,更做不到100% 本地可信,但是我们可以阻止非官方 App 使用,也可以识别重打包,再加上服务端封禁。

安全不是"是否被破解",而是"破解是否还有意义"。

2、一句话总结

Android 安全的本质不是防篡改,而是:"让任何非官方 App 即使能安装,也无法产生价值。"


关于作者(ZFJ_张福杰)


相关推荐
安当加密2 小时前
通过ASP认证系统作为 RADIUS 认证服务器:解决异地办公登录安全问题的实践方案*
运维·服务器·安全
Bigger8 小时前
Flutter 开发实战:解决华为 HarmonyOS 任务列表不显示 App 名称的终极指南
android·flutter·华为
没有bug.的程序员9 小时前
单体 → 微服务演进路径:一个真实电商项目的渐进式转型
jvm·微服务·云原生·架构·电商·gc调优
Xの哲學9 小时前
Linux流量控制: 内核队列的深度剖析
linux·服务器·算法·架构·边缘计算
利剑 -~11 小时前
mysql面试题整理
android·数据库·mysql
喜欢吃豆12 小时前
我把 LLM 技术栈做成了一张“可复用的认知地图”:notes-on-llms 开源仓库介绍
学习·语言模型·架构·开源·大模型·多模态
梁同学与Android13 小时前
Android ---【经验篇】ArrayList vs CopyOnWriteArrayList 核心区别,怎么选择?
android·java·开发语言
沐怡旸14 小时前
【翻译】adb screenrecord 帮助文档
android
FrameNotWork14 小时前
HarmonyOS 教学实战(五):路由、页面生命周期与多页面架构
华为·架构·harmonyos