ridhoae303/ChikiAgeGate

GitHub: ridhoae303/ChikiAgeGate

一个使用 Java 和 JNI 原生代码构建的 Android 年龄验证门组件,为应用提供满18岁的出生日期校验与本地验证状态管理。

Stars: 0 | Forks: 0

Chiki AgeGate banner

Chiki AgeGate

一个使用 Java、JNI 以及原生 18+ 日期验证构建的简洁 Android 年龄门。

Source Repository ridhoae303 on GitHub Chiki AgeGate License

## 关于 Chiki AgeGate 是一个用于 Android 应用的全屏年龄验证门。它会询问用户是未成年人还是 18 岁以上,然后通过原生 C++ 代码检查所选的出生日期,随后才允许应用继续运行。 整个界面均使用 Java 构建,因此没有复杂的 XML 布局迷宫,也没有庞大的 UI 依赖栈。原生端负责处理日期规则、提示字符串以及本地验证 token。 它是一个年龄门,而非身份验证。请勿将其视为实现法律合规的万能神器。 ## 功能特性 - 显示不可取消的全屏验证对话框。 - 提供明确的**未成年**和 **18+** 选项。 - 当用户选择未成年选项时关闭应用。 - 使用自定义的年份、月份和日期选择器。 - 检查闰年、有效日历日期、未来日期以及用户当前的年龄。 - 要求用户年满至少 18 岁。 - 仅将所选的出生日期保留在内存中;实际日期不会保存到首选项中。 - 验证成功后,仅存储本地验证状态 token。 - 使用 `EasyObfuse` 混淆原生字符串。 - 使用随机的原生提示文本,因此开场信息不会总是一成不变的。 - 支持可选的二次出生日期确认流程。 - 包含流畅的进入、退出、选择器、Logo 和无效选择动画。 - 使用来自 Android assets 的自定义 Logo 和字体,并内置后备方案。 - 需要在短时间内按两次返回键才能退出主验证门。 - 无需 XML 主题即可在不同 Android 实现中为 `NumberPicker` 设置样式。 ## 流程 ``` App opens ↓ Was this installation already verified? ├─ Yes → continue └─ No → show Chiki AgeGate ↓ User says "minor"? ├─ Yes → close the app └─ No → select birth date ↓ Native 18+ check ├─ Fail → show feedback and stay locked └─ Pass → save verified token and continue ``` ## 项目结构 除非您的构建设置已有自身的结构,否则请使用以下布局: ``` app/ └── src/ └── main/ ├── java/ │ └── com/chiki/makigate/ │ └── ChikiVerification.java ├── cpp/ │ ├── ChikiVerification.cpp │ └── EasyObfuse.h └── assets/ └── chiki/ └── age_verify/ ├── logo.png └── font.ttf ``` 本 README 使用的横幅位于此处: ``` banner/chiki-agegate-banner.jpg ``` ## 环境要求 - 支持 Java 的 Android 项目 - Android NDK 和 JNI - C++11 或更高版本 - CMake、ndk-build 或其他兼容的原生构建设置 - 一个名为 `libmakigate.so` 的生成原生库 - `ChikiVerification.java` - `ChikiVerification.cpp` - `EasyObfuse.h` Java 类通过以下方式加载原生库: ``` System.loadLibrary("makigate"); ``` 因此,您的原生目标需要命名为 `makigate`。 ## 调用 Chiki AgeGate 从 `Activity` 中调用验证器: ``` import com.chiki.makigate.ChikiVerification; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ChikiVerification.verify(this); } ``` 该方法签名为: ``` public static void verify(Activity activity); ``` ### Smali 匹配的 Smali 调用为: ``` invoke-static {p0}, Lcom/chiki/makigate/ChikiVerification;->verify(Landroid/app/Activity;)V ``` 这里没有 `move-result`,因为 `verify(Activity)` 返回 `void`。此示例还假设 `p0` 包含当前的 `Activity`,这在非静态的 Activity 方法(例如 `onCreate`)内部通常是正确的。 如果 Activity 存储在另一个寄存器中,请将 `p0` 替换为该寄存器。 ## 原生桥接 当前的 Java 类声明了以下原生方法: ``` public static native String nRkVxQpLm(); public static native boolean zMpwQbLrS(int year, int month, int day); public static native boolean qTrLxVmNp(int year); public static native String pXvNqRtKm(String plain); public static native String vLmQrXpNz(String encrypted); ``` 它们的 JNI 导出与此确切的类路径绑定: ``` com.chiki.makigate.ChikiVerification ``` 更改包名、类名或原生方法名意味着也要在 `ChikiVerification.cpp` 中更改匹配的 JNI 符号。JNI 非常严格;一个字符错误就会导致其无法配合工作。 对于 release 构建,请防止此桥接类被 R8/ProGuard 重命名: ``` -keep class com.chiki.makigate.ChikiVerification { *; } ``` ## Assets Chiki AgeGate 会寻找以下文件: ``` assets/chiki/age_verify/logo.png assets/chiki/age_verify/font.ttf ``` `logo.png` 会被居中裁剪为圆形图像。当缺少该 Logo 时,UI 会回退到生成的紫色圆形。 `font.ttf` 用于创作者标题。当无法加载时,会改用 Android 默认的粗体字体。 当前点击 Logo 会打开 `openLogoLink()` 中硬编码的社区链接。在发布分支之前,请将该 URL 替换为您自己的页面、群组或项目链接。 ## 当前默认设置 | 设置 | 当前值 | |---|---:| | 最低年龄 | `18` | | 最早接受的出生年份 | `1980` | | 原生库 | `makigate` | | 首选项文件 | `maki_gate_enc` | | 首选项键 | `vrf` | | 双击退出时间窗口 | `1800 ms` | | 随机提示数量 | `7` | | 二次日期确认 | 禁用 | 最早的出生年份在 Java 和 C++ 中均存在: ``` private static final int MIN_BIRTH_YEAR = 1980; ``` ``` static const int kMinimumBirthYear = 1980; ``` 请同时更改这两个值。仅更新一端会导致选择器与原生验证器之间的行为不一致。 ## 可选的二次确认 Java 端已经包含了一个二次流程,要求用户再次输入相同的出生日期。目前它是禁用的,因为下面的原生方法始终返回 `JNI_FALSE`: ``` Java_com_chiki_makigate_ChikiVerification_qTrLxVmNp(...) ``` 这意味着通过验证的用户通常只需验证一次即可继续。稍后可以通过更改该方法背后的原生策略来启用第二个选择器。 ## 本地验证状态 验证成功后,Chiki AgeGate 会在私有的 `SharedPreferences` 中存储一个经过混淆的 `verified` token。 实际的出生日期不会写入首选项。它仅用于当前的验证流程,随后即被丢弃。 存储的 token 使用轻量级的原生 XOR 和 Base64 例程进行包装。这使其避免了明文显示,但这并非强加密,因此不应被宣称为防篡改存储。 ## 隐私与安全说明 Chiki AgeGate 会在本地执行其出生日期检查。它不会上传输入的日期,也不需要网络请求进行验证。提供的代码中唯一的外部操作是创作者 Logo 链接,该链接会在用户点击 Logo 后打开。 本项目是一个客户端的年龄门。有意图的人可以谎报出生日期、重置本地应用数据、patch APK 或修改验证流程。请将其作为明确的访问屏障和面向用户的确认步骤——而不是将其视为身份证明、政府 ID 检查,或视为对遵守所有法律或平台政策的保证。 为了获得更强的保护,请将其与适合您应用的措施结合使用: - 服务器端账户规则 - 平台家长控制 - 基于区域的合规逻辑 - 代码混淆和完整性检查 - 清晰的隐私和内容声明 - 针对您实际服务的国家/地区进行的适当法律审查 ## 行为说明 - 按下**不,我是未成年人**会清除验证标志并关闭进程。 - 失败或未成年的日期会保持选择器打开,并播放简短的摇晃动画。 - 在主验证门按一次返回键会显示警告;在 `1800 ms` 内再次按下则会退出。 - 在日期选择器内按返回键会返回到主验证门。 - 一旦验证 token 被接受,后续对 `verify()` 的调用将立即返回。 - 清除应用的本地数据会重置验证状态。 ## 自定义 最容易更改的部分包括: - 横幅、Logo 和字体 - 创作者标题和副标题 - 按钮标签 - 对话框颜色和渐变 - 随机原生提示 - 最低年龄 - 最早接受的出生年份 - 社区/项目链接 - 首选项文件和键 - 退出时机 - 二次确认策略 只要同一规则在 Java 和 C++ 两端都存在,请始终保持两者的常量同步。 ## 许可证 Chiki AgeGate 使用 **Chiki AgeGate License**。请在 [`LICENSE`](./LICENSE) 中阅读完整条款。 这是一个源码可见的许可证,而非 OSI 批准的开源许可证。您可以在其条款下学习、使用和修改本项目,但不得抹除原始署名、假装原始作品为您所有,或在未经适当署名的情况下重新分发重命名的副本。 ## 致谢 由 **ridhoae303** 创建。 © 2026 ridhoae303。除许可证中授予的权限外,保留所有权利。
标签:Bash脚本, C++, JS文件枚举, 原生开发(JNI), 安卓开发, 年龄验证, 数据擦除