# ai-passport-otp **Repository Path**: flashaxe/ai-passport-otp ## Basic Information - **Project Name**: ai-passport-otp - **Description**: 口令护照 —— 在 FoloToy AI Passport 上实现的离线硬件动态口令器(TOTP)。含应用源码、配套导入工具与中文像素字体流水线。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-09 - **Last Updated**: 2026-10-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [English](README.md) · **简体中文** # 口令护照 —— 把 AI Passport 变成随身的动态口令器 把 FoloToy AI Passport 变成一台随身可用的动态口令器(TOTP,RFC 6238):屏幕正中一行大字 就是当前验证码,下面一条倒计时条标明还剩几秒,归零自动换新码。账户经蓝牙从手机搬进设备, 验证码在设备本地算出来;配置一次之后不再需要手机和网络。 像素复古的四色界面配硬边大字,操作只有三个按键。 ## 这个仓库是什么 本仓库是上述应用在 FoloToy AI Passport ([`gitee.com/FoloToy/ai-passport`](https://gitee.com/FoloToy/ai-passport))上的 **派生应用源码与配套工具**,形态是一个**叠加层(overlay)**: - **包含**:本应用新增的全部源码、被修改的上游文件、配套工具、生成的字体、主机测试与交付记录。 - **不包含**:板级支持包(BSP)与上游的工程骨架。要构建,请先克隆上游,再用本仓库覆盖 —— 见「怎么构建」。 | 路径 | 内容 | | --- | --- | | `main/` | 应用源码。`app_*.c` 是界面与数据层;`otp_*.c` / `totp.c` 是纯逻辑层,有主机测试覆盖 | | `companion/` | 配套工具:把 Google Authenticator 的导出数据经蓝牙送进设备,并给设备校时 | | `assets/fonts/` | 生成的中文像素字体子集与字形清单 | | `components/bsp/` | 只含本应用改动过的三个 BSP 文件 | | `tools/` | 字体生成、字形覆盖检查、仓库门禁 | | `tests/` | 无需硬件即可运行的主机测试 | | `docs/reference/` | 交付报告与真机测试记录 | ## 怎么用 设备上既没有摄像头也没有键盘,而 Google Authenticator 的导出是一张二维码, 所以同一段文本要靠配套工具经蓝牙搬进设备。这条通道顺带解决了时钟问题: 板子上没有时钟芯片,而 TOTP 需要准确时间。 1. 准备一台电脑或安卓手机,打开配套网页 `companion/web/index.html`(双击即可,页面本身不需要联网)。 2. 在手机上打开 Google Authenticator,选「转移账号 → 导出账号」,拿到二维码或导出文本。 3. 设备开机,按 `确定` 进入账户列表;长按 `确定` 打开菜单,选「蓝牙校时」,再按 `确定` 打开写入闸门。 4. 在配套网页上连接名为 `PassportOTP` 的设备,先发送时间;屏幕出现「校时完成」即成功。 5. 回菜单选「导入账户」,按 `确定` 再次打开闸门;在网页上粘贴导出文本或上传二维码截图后发送。 6. 按 `确定` 返回并选中账户,即可看到大字验证码与倒计时条。之后日常看码不再需要手机和网络。 操作约定:`上/下` 短按移动选中项,`确定` 短按执行本页主操作,`确定` **长按永远向上退一层**。 空闲 30 秒背光降到 20%,90 秒后关闭,任意按键恢复。 配套工具的详细说明(含命令行版、线协议与故障排查)见 [`companion/README.zh_CN.md`](companion/README.zh_CN.md)。 ⚠️ 这条蓝牙通道**没有加密,也没有配对**。写入闸门(180 秒)是可用性与暴露面的限制, 不是密码学保护。请在可信环境里完成首次导入。 ## 怎么构建 本仓库是叠加层,不能单独构建。把它覆盖到上游克隆即可: ```bash git clone https://gitee.com/FoloToy/ai-passport.git cd ai-passport git checkout -b feature/hardware-totp-authenticator # 用本仓库的内容覆盖同名路径 rsync -a --exclude='.git' /path/to/this-repo/ ./ idf.py set-target esp32c3 idf.py build ``` 合并镜像由仓库门禁产出(`./tools/validate.sh` → `build/FoloToy-AI-Passport-full.bin`), 从 `0x0` 刷写: ```bash python -m esptool --chip esp32c3 -p <端口> write_flash 0x0 build/FoloToy-AI-Passport-full.bin ``` 上游的 `demo_*.c` 参考实现**不参与本应用的构建**,但保留在 `main/` 里逐字节不动 —— 这既满足「必须重新设计界面」的约束,也让后续同步上游时不产生冲突。 > **注意**:`tools/check_font_coverage.py`、`tools/validate.sh` 以及 > `tests/test_check_font_coverage.py` 里的仓库级用例,都必须在**完整树**上运行。 > 字形清单的码点取自整个 `main/`(含上游 demo 源码里的字符串字面量), > 因此在只有本应用文件的叠加层里直接运行,会报「清单有、源码没有」。 > 这是叠加层的固有限制,不是缺陷 —— 该文件里其余 14 个用例是自包含的,可单独通过。 ### 重新生成中文字体 界面用的是只含所需字符的 12px 像素字体子集(Fusion Pixel Font,SIL OFL 1.1)。 少收一个字形,屏幕上就会出现占位方块,所以 `main/` 下任何字符串字面量里的非 ASCII 字符 都必须被覆盖;新增中文之后必须重新生成: ```bash ./tools/gen_otp_font.sh # 重新生成字体与清单 python3 tools/check_font_coverage.py --selftest # 证明判据确实能失败,不是空过 ``` ## 验证状态 | 项 | 结果 | | --- | --- | | 构建 | 通过。ESP-IDF v5.5.3,lvgl 9.5.0(按 `dependencies.lock` 锁定),编译无警告。合并镜像 1070288 字节。 | | 主机测试 | 通过。TOTP/HOTP、Google Authenticator 迁移载荷解析、URI 解析、NVS 存储、字形覆盖检查及其自检。 | | 真机测试 | 已进行(2026-10-09)。刷写、启动链路、中文像素字体、按键、BLE 广播、600 秒静置、音频静音寄存器校验均已实测通过。 | | 未验证 | 与真实手机的端到端导入与逐位口令一致性、验证码页的实际渲染(需至少一个账户)、实测走时误差、电量计准确度、真实空闲功耗、任务栈高水位。 | 逐项结论与设备测试记录见 [`docs/reference/flashaxe/hardware-totp-authenticator/README.zh_CN.md`](docs/reference/flashaxe/hardware-totp-authenticator/README.zh_CN.md)。 ## 来源与许可 本仓库是 [FoloToy AI Passport](https://gitee.com/FoloToy/ai-passport) 上的派生应用, 沿用其 MIT 许可(见 [`LICENSE`](LICENSE),版权归 FoloToy 所有)。 - **修改自上游**:`main/main.c`、`main/CMakeLists.txt`、`components/bsp/include/bsp_audio.h`、 `components/bsp/include/bsp_pins.h`、`components/bsp/src/bsp_audio.c`、`tools/validate.sh`、 `assets/README.md`、`assets/README.zh_CN.md` - **本应用新增**:`main/` 下的 `app_*.c/h`、`otp_*.c/h`、`totp.c/h`,以及 `companion/`、 `tests/`、`tools/check_font_coverage.py`、`tools/gen_otp_font.sh`、`assets/fonts/`、`docs/` 中文字体为 Fusion Pixel Font,采用 SIL OFL 1.1,许可证见 [`assets/fonts/FUSION-PIXEL-OFL.txt`](assets/fonts/FUSION-PIXEL-OFL.txt)。