Android / 完整案例 / 阅读约 18 分钟
Aegis:为什么验证码到第 60 秒会变化?
验证器看起来只是六位数字和一个倒计时。跟随公开记录的 REA Aegis 分析,再亲手试试这个可以控制时间的小型实现。
本页内容
还原一种基于时间的验证码算法,在浏览器中实现它,并验证两个 30 秒时间窗口之间的边界。
开始之前演示可以直接使用。若要重复 APK 分析,需要 REA、Aegis v3.4.3、完整的 JDK 17+,以及我们在以下教程中介绍的 jadx 分析后端: Android 教程。
01. 从第 59 秒调到第 60 秒
点击下方两个时间按钮。使用固定的公开测试密钥,第 59 秒得到 287082;第 60 秒得到 359152。再调回第 30 秒,第一组验证码就会出现,因为第 30 秒和第 59 秒属于同一个时间窗口。
公开测试密钥 · SHA-1 · 6 位数字
Unix 时间 59秒 计数器 1
59 ÷ 30 → 计数器为 1。到第 60 秒时,计数器变为 2。
使用 RFC 6238 公开测试密钥的独立教学实现。不涉及账户密钥,也不会在浏览器中调用 REA。
这些数值表示自 Unix 纪元开始经过的秒数,并非钟表显示的秒数。演示实现标准 TOTP,使用公开的 ASCII 密钥 12345678901234567890。它不会读取 Aegis 密钥库,也不会使用账户密钥。
02. 在 APK 中找到基于时间的方法
REA 官方报告 使用 REA 6.1.0 分析了 Aegis v3.4.3。要沿着报告的路径分析,请先 获取该版本,记录其哈希值,再搜索 TOTP 类。下方命令使用 REA 6.4.0。
npx -y [email protected] inspect-android-package "/absolute/path/aegis-v3.4.3.apk" --json
npx -y [email protected] search-android-classes "/absolute/path/aegis-v3.4.3.apk" Totp --json使用工具返回的完整类名查看成员。 getOtp 的时间戳重载很实用,因为可以直接指定时间。请从成员清单中选择这一重载,不要默认同名的第一个方法就是它。
使用 REA 分析 /absolute/path/aegis-v3.4.3.apk 中的 TotpInfo 类。选择接受时间戳的 getOtp 重载。沿调用链追踪计数器编码、HMAC、截断和十进制格式化。还原默认周期、哈希算法和位数。引用查看过的每个方法,区分默认值与各账户的设置。不要执行 APK。03. 还原完整计算过程
发现除以 30 只是起点。上游报告串起了五个阶段:对时间向下取整得到计数器;将计数器编码为八个大端字节;用密钥计算 HMAC;从哈希中截取正的 31 位整数;取模得到六位数字,并保留前导零。
沿工具返回的方法调用继续追踪,不要只依赖熟悉的源码名称。在分析的版本中,优化将生成器辅助方法放在 kotlin.ExceptionsKt下。报告也区分了默认的 SHA-1、六位数字、30 秒与账户自定义设置。
04. 重建规则,测试边界
独立实现还原出的行为,再用公开参考测试向量验证。测试时间边界前后、带前导零的结果,以及六位和八位输出。数学上并不保证相邻时间窗口的验证码一定不同,尽管本示例中确实不同。
为已还原的行为编写一个小型独立 TOTP 实现。仅使用 RFC 6238 公开测试密钥。验证全部六个 SHA-1 参考时间戳的八位结果及其六位余数。测试 29/30 和 59/60 秒边界,保留前导零。说明与分析方法之间的任何差异;不要声称重建了密钥库或 Android 应用。| Unix 时间 | 计数器 | 六位结果 | 验证内容 |
|---|---|---|---|
| 29 | 0 | 755224 | 首个窗口末尾 |
| 30 | 1 | 287082 | 跨过边界 |
| 59 | 1 | 287082 | 同一窗口 |
| 60 | 2 | 359152 | 下一个计数器 |
| 1111111109 | 37037036 | 081804 | 保留前导零 |
05. 理解“133 项验证”的含义
上游项目报告:由选定反编译方法组成的 JVM 测试程序,与独立重建实现,在 133 组输入上结果一致。它没有启动原始 APK。这支持选定算法的一致性,并不能证明完整应用等价。
本站另外编写了 WebCrypto 演示,对六个已发布的 SHA-1 测试向量分别验证两种位数,并将第 0 到第 120 秒的每个整数秒与独立的 Node HMAC 实现进行对比。我们没有重复原始 APK 分析或其 Java 测试程序。
来源: REA 的 Aegis 证据报告 · RFC 6238 测试向量。演示和说明均独立编写,本站未再分发 Aegis 应用源码。