Appearance
aes-gcm-and-frida-detect
1. 实验目标
用最小实现走通两条安全加固链路(对应 docs/00-foundations/11):
- AES-GCM 对称加密:用
javax.crypto完成「密钥生成 → 加密 → 解密」,验证 GCM 的认证标签(Auth Tag)能检测密文被篡改 - Root / Frida 特征检测:运行时采集一组常见逆向特征(进程 maps、frida 端口、su/debuggable),命中即提示风险
本实验以独立 Kotlin/Java 片段形式给出(见「7. 关键源码」),可直接粘贴进任意 JVM / Android 工程运行;暂不接入 Android Host 的 Activity 构建,避免影响宿主 gradle 编译。
2. 工程要点
KeyGenerator生成 256-bit AES 密钥;GCMParameterSpec指定 12-byte IV + 128-bit tagCipher.getInstance("AES/GCM/NoPadding"):最终输出 =IV(12) + ciphertext + tag(16)- 篡改密文后
doFinal抛AEADBadTagException→ 证明认证完整性 - Frida 检测:读
/proc/self/maps是否含frida-agent;探测27042默认端口;检查su/magisk路径与ro.debuggable
3. 运行方式
见「7. 关键源码」,复制函数到工程后直接调用即可。
4. 预期现象
- 正常加解密往返一致;篡改任意密文字节后解密抛
AEADBadTagException - 未注入 Frida 时检测返回空;注入后命中
maps: frida-agent或端口
5. 常见误区
| 误区 | 实际情况 |
|---|---|
用 AES/ECB 更简单 | ECB 不提供语义安全,相同明文块产生相同密文,必须用 GCM/CTR/CBC+HMAC |
| 固定 IV 复用 | GCM 严禁 IV 复用,否则密钥流泄露、可伪造 |
| Root/Frida 检测能 100% 防住 | 只能提高门槛(增加对抗成本),专业绕过(改端口、隐藏 maps)存在 |
6. 对应知识库文档
7. 关键源码
kotlin
// AES-GCM 加解密 + 篡改检测
fun aesGcmRoundTrip() {
val key = KeyGenerator.getInstance("AES").apply { init(256) }.generateKey()
val iv = ByteArray(12).also { SecureRandom().nextBytes(it) }
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, key, GCMParameterSpec(128, iv))
val plain = "secret-payload".toByteArray()
val enc = iv + cipher.doFinal(plain) // 真实用法必须把 IV 拼到密文前
// 篡改最后一个密文字节
val tampered = enc.copyOf().also { it[it.lastIndex] = (it[it.lastIndex].inc()).toByte() }
val iv2 = tampered.copyOfRange(0, 12)
val ct2 = tampered.copyOfRange(12, tampered.size)
cipher.init(Cipher.DECRYPT_MODE, key, GCMParameterSpec(128, iv2))
try {
cipher.doFinal(ct2)
println("解密成功(不应到达:篡改未被发现)")
} catch (e: AEADBadTagException) {
println("AEADBadTagException:密文被篡改,认证失败 ✅") // 预期命中
}
}kotlin
// Frida / Root 特征检测(最小集)
fun detectFrida(): List<String> {
val hits = mutableListOf<String>()
runCatching {
File("/proc/self/maps").readText().lineSequence()
.find { it.contains("frida", ignoreCase = true) }
?.let { hits += "maps: frida-agent" }
}
runCatching {
Socket("127.0.0.1", 27042).use { hits += "frida-server:27042" }
}
listOf("/system/xbin/su", "/system/bin/su", "/sbin/magisk").forEach {
if (File(it).exists()) hits += "root: $it"
}
return hits
}接入状态
✅ 已接入 Android 宿主 App:对应 AesGcmAndFridaDetectActivity,从 MainActivity → 「打开 AES-GCM 加密与 Frida 检测实验室」进入。上面「运行方式」里的 AES-GCM 加解密与 Frida 检测步骤,即在该 Activity 内运行(无需任何权限)。