抓包分析中,未知参数的生成逻辑通常分为三类:随机数、标准密码学算法(编码/摘要/加解密)、开发者自定义实现。在未确认算法类型前直接对函数名逐个 Hook,效率低且容易遗漏。正确路径是先依据码表特征与输出长度识别算法类型,再在 MessageDigest 的 update/digest 上部署通杀 Hook 截获明文。本文系统梳理 Android 逆向所需的密码学基础:HEX 与 Base64 的识别特征、摘要算法的长度判定、MD5 实操与加盐处理,最终落地到 update/digest 全重载通杀方案。
一、为什么要学密码学
客户端到服务端的数据包里,总有参数你不知道怎么来的。三类可能:随机生成、标准算法加密/摘要、开发者自写逻辑。认不清类型,后面 Hook 再猛也像盲人摸象。
二、加密落在哪一层
Android 上常见三条线:
Java:有系统 API,方法名相对固定,适合按名字定位。 Native(so / C/C++):没有统一系统 API,可自实现或接模块,名字还能混淆——更要靠算法特征识别。 JavaScript:同样没有现成系统 API,多用 CryptoJS、jsencrypt 等第三方库。
三、密码学里先学哪些
消息摘要(Hash):MD5、SHA、MAC。 对称加密:DES、3DES、AES。 非对称加密:RSA。 数字签名:MD5withRSA、SHA1withRSA、SHA256withRSA 等。
标准算法在各语言里的实现结果应当一致——Java 算出来的,和 JavaScript 按同一标准算出来的,应对得上。这对「本地复现 / 对照验证」很关键。
四、标准 HEX 与非标准码表
摘要、密文算完往往是字节数组,要给人看或传输,常编码成 HEX。标准码表就是:0-9、a-f(或大写 A-F)。实现上常见一张 16 格字符表,按半字节查表拼出字符串。
非标准 HEX:把表改掉,例如前几位换成 q、w、r、t、y……逻辑还是「半字节查表」,但肉眼不像十六进制。逆向时看到怪字符「编码结果」,先搜码表,别一上来当私有加密。
五、Base64:编码,不是加密
Base64 用 64 个可打印字符表示任意二进制:A-Z、a-z、0-9、+、/,以及填充 =。它是编码,不是加密——可逆、易解码,不适合当「保密手段」。
RSA 密钥、密文字节、图片等含不可见字符,直接当文本传容易乱码、截断。Base64 把它们变成安全文本。细节上:每个字符约对应原数据 6 bit;编码后长度常是 4 的倍数;原字节数是 3 的倍数时可不填充。
Android / Java:android.util.Base64、java.util.Base64(高版本);OkHttp/Okio 里 ByteString 也有 base64()。Java 层可按方法名快速定位;so 层更多靠输入输出和码表特征认。
六、URL 场景下的 Base64
标准 Base64 里的 + 和 /,走 URL 时容易被弄成空格或歧义。常见做法:再做 URL 编码,或换成 - 和 _(URL 安全 / URL_MAP)。看到「像 Base64 但字符集略怪」,先核对是不是 URL 安全变体。
七、消息摘要:不可逆,长度是身份证
消息摘要不可逆:任意长度输入,输出长度固定。不同算法靠结果长度分辨——例如 MD 系列常见 128 bit,SHA-1 为 160,SHA-256 为 256,以此类推。
还有一条实用特征:可以不传任何数据,照样算出「空输入」的摘要。空摘要是固定值,常用来核对实现是否标准、Hook 是否打到真算法。
八、MessageDigest 与 MD5
Java 侧用 MessageDigest.getInstance("算法名") 拿到实例。典型流程:update 喂数据 → digest 出字节数组 → 再 HEX 或 Base64 编码成可读串。
MD 系列里 MD2/MD5 在常见 Java 实现中摘要长度 128;MD4 等可能要 Bouncy Castle。示例:MessageDigest md5 = MessageDigest.getInstance("MD5");md5.update("xiaojianbang".getBytes());md5.digest();
九、空串、普通串、加盐
空数据:直接 digest(),标准 MD5 空摘要常见为 D41D8CD98F00B204E9800998ECF8427E(HEX)。用来验环境、验 Hook。
普通字符串:update(字符串.getBytes()) 再 digest,再用 HexBin.encode 或自写 hex 打出来。
加盐 MD5:盐一般不会太复杂。空数据打进去,若业务把盐拼进摘要路径,结果常常等价于「只对盐做 MD5」——拿去 CMD5 一类站点查,有机会直接爆出盐。getInstance 也可换成 SHA-256 等,指定任意算法名。
十、通杀挂点:update 与 digest
摘要通杀不盯某一个业务方法名,盯 MessageDigest 数据入口:update 负责喂明文(或分段数据),digest 负责出摘要。两个点都能在「加密前」碰到明文相关数据,所以都是挂点。
update 有多条重载(整段字节、带 offset/len 的分段等)——要通杀,所有重载都挂,否则明文从另一条重载溜走。
十一、算法名不一定非挂 getInstance
想知道当前是 MD5 还是 SHA,不一定死磕 getInstance。MessageDigest 实例上的 getAlgorithm() 可以直接拿到算法名。通杀脚本里先捞明文,再顺手打算法名,定位更快。
十二、启动器进程和 App 进程
直接注入时可能落在启动器进程;App 起来后再注入,才是业务进程。两种情况下,都可能摸到 okhttp 相关的 ByteString(例如 com.android.okhttp.okio.ByteString)。编码、正文、部分加密链路会经过它,适合当辅助观察点。
实操上:确认 Java.use 能拿到类,再决定往编码还是摘要链路上挂。进程不对,类找不到,别先怀疑算法名写错。
十三、总结
1. 参数来路三种:随机、标准算法、自写逻辑;先认类型再 Hook。
2. 加密常见落点:Java 系统 API、so 自实现、JS 第三方库(CryptoJS/jsencrypt)。
3. 要学:摘要、对称、非对称、数字签名;标准算法跨语言结果应一致。
4. HEX 标准码表是 0-9a-f;改表就是非标准/变形编码。
5. Base64 是编码不是加密,可逆,不适合当保密方案。
6. Base64 解决不可见字符传输;输出长度常为 4 的倍数。
7. URL 场景常用 URL 编码或 -/_ 替换 +/(URL_MAP)。
8. Java/Android 可用 util.Base64;Okio ByteString 也有 base64。
9. 摘要不可逆、定长;不同算法靠输出长度分辨。
10. 空输入也能出摘要;空摘要可校验实现与 Hook。
11. MessageDigest:getInstance → update → digest → HEX/Base64。
12. MD5 等 MD 系列常见 128 bit;注意实现库差异。
13. 加盐时可用空数据打,结果常接近「盐的摘要」,便于 CMD5 查。
14. 通杀挂点:update 与 digest;明文多在这两处出现。
15. update 所有重载都要挂,避免漏喂数入口。
16. 算法名可用实例 getAlgorithm(),不必只盯 getInstance。
17. 启动器注入与 App 注入进程不同;ByteString 两类进程都可能找到。
18. 顺序建议:认编码/摘要 → 对长度与码表 → MD5 实操 → update/digest 通杀。
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……



