一款离线、开源、现代化的 Android 动态口令管理器。2.0 版本使用 Flutter 与成熟密码学组件完整重构,不再追求 64 KiB 的实验性体积,而是优先保证算法兼容性、数据安全和日常可用性。
当前版本:
2.0.0· 平台:Android arm64-v8a · 许可证:MIT
- 扫描 Google Authenticator 等工具生成的标准
otpauth://二维码。 - 支持 TOTP(RFC 6238)和 HOTP(RFC 4226)。
- 支持 HMAC-SHA-1、HMAC-SHA-256、HMAC-SHA-512。
- 支持 6–10 位口令、1–300 秒 TOTP 周期以及 HOTP 计数器。
- 多账户长期保存、搜索、拖动排序、收藏、编辑和删除。
- 一键复制动态口令,30 秒后自动清理相同剪贴板内容。
- 可选指纹、4–12 位 PIN 或九宫格图案解锁。
- 进入后台后立即或按 30 秒、1 分钟、5 分钟、15 分钟自动锁定。
- 禁止系统截图、录屏捕获以及最近任务缩略图泄露。
- 密码保护的加密备份、恢复与重复账户合并。
- 深色模式、Material 3 界面、动态倒计时与账户识别颜色。
- 不申请网络权限;二维码模型随 APK 提供,首次扫描也能离线工作。
GitHub Release 提供 DRPA-keychain-v2.0.0-arm64.apk:
- ABI:
arm64-v8a - 最低系统:Android 7.0 / API 24
- 目标系统:Android API 36
- 包名:
q.a,与 1.0 版一致 - 发布签名证书 SHA-256:
6d5d5a5868724c7bf75b8f9c0b97678397496555b7a79b6dfb553a3471183987
安装前可使用 Release 中的 SHA256SUMS.txt 校验文件完整性。
2.0 版本不再自行维护 OTP、扫码、密钥存储、生物识别或备份加密核心:
| 能力 | 组件 | 说明 |
|---|---|---|
| TOTP / HOTP | otp |
实现 RFC 4226、RFC 6238 以及 SHA-1/256/512 |
| 二维码 | mobile_scanner |
CameraX + Google ML Kit Barcode Scanning |
| 设备加密存储 | flutter_secure_storage |
Android Keystore、RSA-OAEP 密钥封装与 AES-GCM 数据加密 |
| 指纹验证 | local_auth |
调用 Android BiometricPrompt |
| PIN/图案与备份 | cryptography |
Argon2id、AES-256-GCM 与常量时间校验 |
| 文件选择 | file_picker |
Android Storage Access Framework |
应用代码主要负责账户模型、otpauth 参数映射、界面、交互以及安全状态管理。第三方许可证见 THIRD_PARTY.md。
标准二维码示例:
otpauth://totp/Example:alice@example.com?
secret=BASE32_SECRET&issuer=Example&algorithm=SHA256&digits=8&period=45
解析规则:
| 参数 | TOTP | HOTP | 支持值 |
|---|---|---|---|
secret |
必需 | 必需 | Base32 |
issuer |
可选 | 可选 | 任意文本 |
algorithm |
可选 | 可选 | SHA1、SHA256、SHA512 |
digits |
可选 | 可选 | 6–10;未指定时为 6 |
period |
可选 | — | 1–300;未指定时为 30 |
counter |
— | 必需 | 非负整数 |
test/otp_account_test.dart 使用 RFC 6238 官方 SHA-1、SHA-256、SHA-512 向量验证核心库输出。
账户列表不是普通 SharedPreferences 或明文数据库。完整 JSON 由 flutter_secure_storage 写入 Android Keystore 保护的 AES-GCM 存储;应用同时设置:
android:allowBackup="false"android:fullBackupContent="false"android:usesCleartextTraffic="false"- 移除
INTERNET与ACCESS_NETWORK_STATE权限
MainActivity 在 Flutter 首帧之前设置 Android FLAG_SECURE。系统截图、普通录屏和最近任务页面因此不会包含应用内容。该能力始终开启,不依赖应用锁设置。
- 指纹:通过 Android 系统
BiometricPrompt验证,应用不接触指纹模板。 - PIN / 图案:随机 128 位盐;Argon2id 使用 16 MiB 内存、2 次迭代和 2 路并行;仅保存派生验证值。
- 连续失败达到 5 次后执行递增长度的尝试冷却。
- 可设置进入后台后的锁定延迟,也可从首页立即锁定。
备份格式不输出明文密钥:
- 随机生成 128 位盐。
- 使用 Argon2id(32 MiB、2 次迭代、2 路并行)从备份密码派生 256 位密钥。
- 使用 AES-256-GCM 加密账户 JSON。
- 固定 AAD 标识格式,GCM 标签验证密码和文件完整性。
- 导入时限制 KDF 参数范围,避免异常文件造成过量资源消耗。
备份密码没有存入应用;丢失密码后对应备份将保持不可读。
64 KiB 原生实验版依赖极端裁剪和手写逻辑,难以兼顾成熟扫码栈、Flutter UI、Keystore、生物识别与完整算法。2.0 版本选择“可维护且离线可用”的体积预算。
arm64 Release 的主要体积来源:
| 内容 | 约占用 | 原因 |
|---|---|---|
Flutter libflutter.so |
11.1 MiB | Flutter arm64 引擎 |
Dart AOT libapp.so |
4.8 MiB | 应用 UI、状态和依赖代码 |
ML Kit libbarhopper_v3.so |
4.7 MiB | 本地二维码识别核心 |
R8 后的 classes.dex |
1.3 MiB(压缩后) | Android 插件和安全组件 |
| 模型、资源和元数据 | 约 1 MiB | 离线 ML Kit 模型、Material 资源与许可 |
- 仅发布 arm64-v8a:Gradle 同时设置
abiFilters和 JNI 排除规则,剔除 x86、x86_64 与 armeabi-v7a 扫码库。 - R8 与资源收缩:
isMinifyEnabled=true、isShrinkResources=true。 - Dart AOT 混淆:Release 使用
--obfuscate --split-debug-info。 - 图标树摇:Material Icons 从约 1.6 MiB 缩减至约 7 KiB。
- 无图片素材和第三方字体:图标、渐变、卡片和进度环均由 Flutter/Android 矢量绘制。
- 不加入大型状态框架或数据库:使用
provider和单条 Keystore 加密文档。 - 捆绑扫码模型:比可下载模型大约多 3–10 MiB,但没有 Google Play 服务或网络时仍能扫码。这是有意保留的功能性取舍。
若部署环境始终具备 Google Play 服务,可在 android/gradle.properties 添加:
dev.steenbakker.mobile_scanner.useUnbundled=true这会进一步减少 APK,但扫码模型需要首次使用时下载;官方 Release 采用离线捆绑模式。
要求:
- Flutter
3.44.7/ Dart3.12.2 - JDK 21
- Android SDK Platform
37.0、Build Tools37.0.0 - Android NDK(Flutter 默认版本)
flutter pub get
flutter analyze
flutter test
flutter build apk `
--release `
--target-platform android-arm64 `
--obfuscate `
--split-debug-info=build/symbols默认开源构建使用 Android debug signing。要生成可覆盖官方版本的构建,需要持有相同发布私钥,并在 android/key.properties 配置:
storePassword=...
keyPassword=...
keyAlias=...
storeFile=../../path/to/release.jks私钥、密码和 key.properties 均已加入 .gitignore。
lib/
├─ core/
│ ├─ otp_account.dart # 账户模型、otpauth 映射、调用 otp 库
│ └─ security.dart # Keystore、应用锁和加密备份
├─ state/app_state.dart # 账户和安全状态
└─ ui/ # Material 3 页面与组件
android/
└─ app/src/main/kotlin/q/a/MainActivity.kt # FLAG_SECURE
test/
├─ otp_account_test.dart # RFC 6238 与 URI 测试
└─ backup_test.dart # 加密备份往返测试
- 不含统计、广告、遥测或云同步。
- 不申请网络权限。
- 相机画面仅在设备上交给捆绑版扫码组件处理。
- 密钥、PIN、图案和备份密码不会上传。
项目采用 MIT License。问题与改进建议可通过 GitHub Issues 提交。