Android混淆和加密技术

在Android开发与逆向对抗中,加密(Encryption)混淆(Obfuscation)是保护APP核心逻辑和数据安全的两大支柱。

简单来说:混淆是为了让人看不懂代码逻辑,加密是为了让人拿不到原始数据。

以下是Android中主流的加密与混淆技术总结:


一、 代码混淆技术 (Code Obfuscation)

混淆的主要目的是增加逆向分析的成本,使反编译出来的代码难以阅读。

  1. 名称混淆 (Name Obfuscation)

    • 工具:ProGuard, R8 (Android Studio 默认)。
    • 原理:将类名、方法名、变量名改为无意义的短字符(如 abc)。
    • 效果:虽然逻辑还在,但失去了语义,增加了阅读难度。
  2. 字符串混淆 (String Obfuscation)

    • 原理:默认情况下,ProGuard 不混淆字符串。硬编码的 API 地址、Key 会直接暴露。字符串混淆会将这些常量加密,在运行时动态解密。
    • 工具:DexGuard (付费), 某些自研脚本。
  3. 控制流平坦化 (Control Flow Flattening)

    • 原理:将原本清晰的 if-else 或 switch 逻辑打乱,改写为一个由 switch 和 while 循环组成的巨大“分发器”。
    • 效果:F5(反汇编)出来的代码逻辑像“面条”一样杂乱,极难分析业务流程。
  4. 算术运算混淆

    • 原理:将简单的算术运算(如 a = b + 1)替换为极其复杂的等效数学公式。

二、 加密技术 (Data Encryption)

加密侧重于保护敏感数据在存储和传输过程中的安全。

  1. 存储加密

    • 数据库加密:使用 SQLCipher 对 SQLite 数据库进行全盘加密。
    • SP 加密:使用 EncryptedSharedPreferences(Jetpack Security 库)加密本地配置。
    • 文件加密:对 Assets 或资源文件进行 AES 加密,运行时解密。
  2. 传输加密 (网络层)

    • HTTPS/TLS:基础物理层加密。
    • 双向认证 (Mutual TLS):客户端也带证书,防止中间人攻击。
    • SSL Pinning (证书固定):在 APP 内硬编码服务器证书指纹,防止 Charles/Fiddler 抓包。
  3. 核心密钥管理

    • Android Keystore 系统:将密钥存储在硬件隔离区域(TEE),程序只能使用密钥,无法导出原始密钥。

三、 Native 层保护 (C/C++ 层)

由于 Java 容易被反编译,开发者常将核心逻辑写在 C/C++ 中(NDK),并进行更深层的保护。

  1. OLLVM (Obfuscator-LLVM)
    • 基于 LLVM 编译器的后端混淆,可以对 C/C++ 代码进行指令替换、虚假控制流、控制流平坦化。
  2. SO 文件加密
    • 对生成的 .so 文件进行加壳或段加密,只有在 APP 启动加载时才在内存中解密。

四、 加固/加壳技术 (App Hardening)

这是目前国内 Android 安全的主战场,通常由第三方厂商(如腾讯、网易、加固宝等)提供。

  1. 第一代:DEX 整体加密
    • 将整个 classes.dex 加密存放在 Assets,启动时由壳代码(Stub)解密后加载到内存。
  2. 第二代:函数抽取/动态加载
    • 将 DEX 中的方法体(CodeItem)清空,在运行时动态将代码填充回内存。这让内存 Dump 变得困难。
  3. 第三代:VMP (虚拟机保护)
    • 原理:最强形态。将原始 Java 指令转换为自定义的私有指令集,并在 APP 内内置一个自定义的解释器执行。
    • 效果:逆向者即使反编译,看到的也是一堆无法识别的自定义指令,彻底封死反编译之路。

五、 环境监测与反调试 (Environmental Detection)

虽然不属于加密和混淆,但它们是逆向对抗的关键。

  • 反调试 (Anti-Debug):检测 ptraceisDebuggerConnected,一旦被调试则崩溃。
  • 反 Root/反模拟器:检测是否存在 su 文件,检测硬件特征,拒绝在不安全环境下运行。
  • 签名校验:在运行时检测当前签名的 Hash。如果逆向者篡改代码并重新打包,签名改变,APP 停止运行。
  • 反 Hook 监测:检测内存中是否存在 Xposed、Frida 等框架的残留特征。

总结对比

技术项解决的问题常用手段难度等级
代码混淆逻辑阅读难度R8/ProGuard, 控制流平坦化中等
数据加密数据被窃取AES, RSA, Keystore, SQLCipher中等
Native 保护底层逻辑泄露OLLVM, JNI 隐藏
加壳加固整体反编译DEX 加密, 方法抽取, VMP极高

逆向学习者的视角:看到混淆要学会耐心调试;看到加密要找Hook 点(参数拦截);看到加壳要学会脱壳(内存镜像拉取);看到 VMP 建议换个简单的 APP 练手

了解常见加密算法的实现有助于快速进行源码分析和参数定位,具体的代码实现就不再贴出来了,笔者总结了一些可作为关键词检索的特征词:

1. MD5 (Message Digest Algorithm 5)
  • 算法简介:哈希(散列)算法,不可逆。将任意长度的数据映射为固定长度(128位,通常显示为 32位十六进制字符串)。
  • 核心特点
    • 结果长度固定:32位(如 5d41402abc4b2a76b9719d911017c592)。
    • 雪崩效应:输入微调,结果全变。
  • 逆向检索关键词
    • 代码层MD5MessageDigesthashhex_md5.
    • 特征常量(魔数)0x674523010xefcdab890x98badcfe0x10325476(这些是 MD5 初始化的核心幻数)。
    • 库名crypto-jsblueimp-md5hash.js.

2. AES (Advanced Encryption Standard)
  • 算法简介:对称加密算法(加密和解密用同一把钥匙),是目前最流行的加密标准。
  • 核心特点
    • 要素:Key(密钥)、IV(偏移量)、Mode(模式:ECB/CBC/CFB/OFB)、Padding(填充:PKCS5/PKCS7)。
    • Key 长度通常为 16, 24, 32 字节。
  • 逆向检索关键词
    • 模式名AESCBCECBCFBCTR.
    • 填充名PKCS5PaddingPKCS7PaddingZeroPadding.
    • 代码层Cipher.getInstanceSecretKeySpecIvParameterSpecenc.Utf8.parse.
    • 库名CryptoJSpycryptodome (Python), Crypto.

3. RSA (Rivest-Shamir-Adleman)
  • 算法简介:非对称加密算法。有公钥私钥之分,公钥加密的数据只能用私钥解。
  • 核心特点
    • 通常用于加密“对称加密的密钥”,或者用于数字签名。
    • 速度慢,但安全性高。
    • 标识:常见以 -----BEGIN PUBLIC KEY----- 开头的长字符串。
  • 逆向检索关键词
    • 关键术语RSAPublicKeyPrivateKeyModulus (模数), Exponent (指数, 常见 010001 或 65537)。
    • 文件格式.pem.der.crt.key.
    • 代码层setPublicKeysetPrivateKeyX509EncodedKeySpecRSASSAPKCS1v15.
    • 库名jsencryptnode-rsaBigInt.

4. HMAC (Hash-based Message Authentication Code)
  • 算法简介:利用哈希算法(如 MD5, SHA1, SHA256),结合一个密钥生成的摘要。
  • 核心特点
    • 相比普通哈希,多了一个 SecretKey(盐值)。
    • 常用于 API 的 signature(签名)校验。
  • 逆向检索关键词
    • 算法组合HmacMD5HmacSHA1HmacSHA256.
    • 代码层Mac.getInstanceHmacsigsignaturesign.
    • 特征:通常在代码中会看到两个输入:Message 和 Key

5. DES (Data Encryption Standard)
  • 算法简介:较早的对称加密算法。由于 Key 较短(56位有效位),目前已被 AES 取代,但在老旧系统或某些 APP 协议中仍可见。
  • 核心特点
    • 块大小为 64 位。
    • 3DES (Triple DES):DES 的增强版,应用更广,对数据进行三次 DES 加密。
  • 逆向检索关键词
    • 名称DESDESede (即 3DES), TripleDES.
    • 代码层DES/CBC/PKCS5PaddingDESKeySpec.
    • 库名:同 AES,通常都在 Crypto 库中。

当你在开发者工具(F12)或 Jadx 中搜索时,建议按以下优先级操作:

  1. 搜“参数名”:先搜请求里的加密参数名(如 signtoken_signature)。
  2. 搜“特征单词”
    • 搜 JSON.stringify:这是加密前的最后一步,看数据是在哪被序列化的。
    • 搜 encrypt(decrypt(:寻找加密函数入口。
    • 搜 setPublicKey:基本就是 RSA。
    • 搜 iv:mode::基本就是 AES 或 DES。
  3. 搜“常数/魔数”
    • 遇到大量位运算逻辑,搜索 MD5 的初始化常量(如 0x67452301)。
    • 搜索 Base64 码表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
  4. 打断点(XHR Breakpoints)
    • 如果你知道请求的 URL,直接在 Network 面板右键该请求,选择 "XHR Breakpoints",当程序再次发送该请求时会自动停在加密完成的那一刻,然后通过 Call Stack(调用栈) 向上回溯。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值