Android · 开锁全程离线 · MIT 开源

宿舍门禁,一点即开

TmallKey 按字节复刻天猫校园宿舍 BLE 蓝牙锁的开锁协议, 脱离天猫校园独立运行 —— 不 hook、不注入、不读取它的进程。 导入一次凭证,之后哪怕飞行模式也能开门。

最新版 — 体积 — Android 8.0+
FEATURES

为什么用它,而不是每次打开天猫校园

协议层的活儿一次做对,之后剩下的就是「点一下」。

完全离线

开锁不发起任何网络请求,飞行模式下可用。门锁本来就不联网,钥匙只在手机本地。

一次点击,亚秒级

冷启动首次约 1.2 秒,60 秒内再开约 0.4 秒。支持桌面快捷方式与快捷设置磁贴。

不碰原 App

不 hook、不注入、不读取天猫校园进程,只按抓到的报文逐字节复刻 BLE 协议。

凭证硬件级加密

activationKey 由 Android Keystore 的 AES-256-GCM 加密后落盘,密钥不可导出、随卸载销毁。

内置门锁仿真器

没有真机也能跑通完整开锁流程与协议回归,改动协议层有黄金向量兜底。

应用内更新

6 个加速镜像逐级回退,下载后校验 ZIP 魔数与 sha256,同签名直接覆盖安装。

GET STARTED

三步开门

唯一的门槛是「拿凭证」:需要让天猫校园自己开一次锁,在那一刻把 activationKey 取出来(补丁版会自动同步,root / adb 方式则从日志里读)。逐步操作见下方 完整使用教程。

STEP 01

拿凭证

免 root 用「补丁版天猫校园」,已 root 用「root 一键抓取」:

  • 免 root(推荐):装补丁版天猫校园 → 登录 → 在它的门锁页点一次开锁, 钥匙会自动同步进 TmallKey —— 不用导出、不用点导入、不用电脑。
  • 已 root:TmallKey →「+ 添加门锁凭证」→「root 抓取」,一次拿齐钥匙和饮水登录态。
  • 排障:手机开 USB 调试连电脑,跑 fktm/p0_capture.bat 抓 logcat。
STEP 02

导入

补丁版抓到的锁会自动出现在门锁列表,不用做任何操作;root 抓取会填进表单,确认保存即可。 也可以手工填地址 + 32 位 activationKey,或粘贴电脑端导出的 credentials.json。

STEP 03

开锁

回首页点那个大按钮。首次会申请蓝牙权限,允许一次即可。之后就是「一点即开」。

DOWNLOAD

下载安装

直接装 APK 即可,无需应用商店。当前只有 Android 版。

TmallKey 最新版 stable
文件名
—
版本号
—
大小
—
SHA-256
—
更新说明
—

国内直连 GitHub 较慢时,可换下面的加速镜像下载(同一个文件):

安装提示:首次安装需要在系统里允许「安装未知应用」;如果已装过旧版,可直接覆盖安装(签名一致), 数据与凭证都会保留。不要用不同签名的包覆盖,那会装不上。
天猫校园 · LSPatch 补丁版 5.0.0 内嵌凭证同步模块

国内直连 GitHub 较慢时,可换下面的加速镜像下载(同一个文件):

与官方版同包名,只能装一个(切换需卸载重装并重新登录)。
TUTORIAL

完整使用教程

全程不需要 root。你需要的只有三样东西:一部 Android 手机、一扇你本人有权开启的门锁,以及一个能正常开锁的天猫校园 App。

手机Android 8.0(API 26)以上,具备蓝牙
天猫校园已登录、已绑定该门锁,能正常开锁
TmallKey从本页上方下载 APK 安装,或去 Releases
补丁版天猫校园免 root 必需,见下文与本页下载区(与官方版同包名,只能装一个)
凭证是两样东西 —— ① activationKey:32 位十六进制,等价于这把锁的钥匙; ② 门锁的 BLE 地址:形如 AA:BB:CC:DD:EE:FF。

第 1 步 · 拿到凭证

钥匙是服务端按门下发的,只有天猫校园知道、也只会下发给它。所以要「拿」到钥匙,就得让它自己开一次锁,同时把过程记下来。有 root 走 root 一键抓取;没 root 用补丁版天猫校园。

注意:仅仅打开门锁页是不够的。列表接口不下发钥匙,activationKey 只在 点「开锁」那一刻才由页面传给原生层 —— 所以第一次必须真的点一次开锁(门开一下就行)。

装一个「补丁版天猫校园」(本页下载区就有),登录后点一次开锁, 钥匙和饮水登录态都会自动同步进 TmallKey。不需要 root、不需要电脑、不需要导出任何文件。

① 安装补丁版天猫校园

到本页「下载安装」区下载「天猫校园 · LSPatch 补丁版」并安装 (国内直连慢就用下载区的镜像)。它与官方版同包名、只能装一个:如果手机里已装官方版, 需要先卸载(登录态会重置,补丁版里重新登录一次即可,和平时登录一样)。

② 登录,并进「门锁」页

  1. 打开补丁版天猫校园,用手机号 + 验证码登录(与官方版同一账号);
  2. 进入「门锁」页,等锁的列表刷出来。

③ 在门口点一次「开锁」

这一步不能省:钥匙只在点开锁的瞬间才从页面传到原生层。 门开一下就好,之后就不用再碰天猫校园了。

④ 回到 TmallKey,锁已经在了

切回 TmallKey 的「门锁」页,新锁会自动出现(默认名「门锁 + MAC 尾号」,可改名)。 点一下卡片上的「开锁」就能验证:钥匙是离线 BLE 静态数据,一次导入永久有效。

⑤ 顺手把饮水也打通

补丁版登录时会把校园会话(.confong.cn 的 cookie2)一起带过来, TmallKey 的「饮水」页会自动同步登录态,扫码接水不需要额外操作。

手机已 root(KernelSU / Magisk)时的最短路径:一次抓齐门锁钥匙和饮水登录态。 不需要电脑、不需要换掉官方天猫校园。

① 在 root 管理器里允许 TmallKey

打开 KernelSU / Magisk → 超级用户 → 给 TmallKey 授权。 (fkTM 首次点抓取时也会自动弹授权框,允许即可。)

② 点「root 抓取」,去开一次门

TmallKey → 门锁页 → 「+ 添加门锁凭证」→ 点「root 抓取」按钮, 然后切到天猫校园点一次开锁。开锁被检测到后自动完成:

  • 门锁钥匙 → 自动填入下方表单,确认后点「保存」;
  • 饮水登录态 → 自动导入(接水功能立即可用)。

③ 开锁后 4 分钟内没等到日志?

确认天猫校园里能正常开锁(锁没电、蓝牙没开都会导致没日志), 然后回到 TmallKey 再点一次「root 抓取」。

适合排障:没有 root、也不想换掉官方天猫校园时,用电脑直接抓 logcat 读钥匙。

① 准备

  1. 手机打开「开发者选项」→「USB 调试」;
  2. 电脑装好 platform-tools(即 adb);
  3. 数据线连上电脑,执行 adb devices,手机上确认「允许 USB 调试」—— 能看到设备序列号即可。

② 开始抓取

下载仓库里的 fktm/p0_capture.bat,Windows 直接双击即可(它会自动清空日志缓冲、开始抓取,结束后自动跑校验)。其他平台手动执行下面两条:

推荐项是本页同源文件,点了直接下载;直连与镜像指向 GitHub 上的原始文件,部分浏览器会直接把脚本内容显示出来 —— 右键「另存为」保存即可。

adb logcat -c
adb logcat -v time \
  VocLockHelperV2:V VocLockHelper:V VocLockJsBridge:V VocUnlockBridge:V \
  BluetoothHelper:V VocLockManager:V VocLockSession:V VocLockBridge:V \
  ZMUnlockBridge:V VocStatistics:V VocLogger:V Logger:V TLog:V \
  '*:S' > p0_capture.txt

③ 去开一次门

保持数据线连接(或用 adb tcpip 走无线),走到门口用天猫校园点一次开锁,等门打开。

④ 停止抓取,读出凭证

回到电脑按 Ctrl+C 停止抓取。此时 fktm/credentials.json 就是 TmallKey 可直接识别的 JSON,可以进入下一步。也可以手动跑一遍校验:

cd fktm
pip install pycryptodome
python cli.py verify --log p0_capture.txt

输出里直接就有你要的两项:

activationKey : 0123456789ABCDEF0123456789ABCDEF
macAddress    : AA:BB:CC:DD:EE:FF
日志里没打印 activationKey 也能拿到。密钥派生是可逆的 —— actualAesKey = randomNumber XOR activationKey,而 randomNumber(0D 响应明文)和 actualAesKey 日志里都有。 logparse.py 会自动反解,并且要求多组独立会话解出同一个值才采信,解不一致会拒绝下结论。

方式怎么选

补丁版天猫校园(免 root)root 一键抓取电脑 adb
需要电脑否否是
需要 root否是否
需要换掉官方天猫校园是(同包名,二选一)否否
同时拿饮水登录态是(登录即带过来)是否
主要风险官方版与补丁版只能装一个需在 root 管理器里授权 TmallKey装驱动、系统日志策略差异
适用绝大多数用户(推荐)已 root 的手机排障

第 2 步 · 导入凭证

在 TmallKey 首页点「+ 添加门锁凭证」,有三种填法:

  • 手工填写—— 填「名称」(默认「宿舍门」)、「门锁地址」、activationKey,然后保存。地址必须是 AA:BB:CC:DD:EE:FF 格式,钥匙必须是 32 位十六进制。
  • 粘贴 JSON—— 直接粘贴 fktm/credentials.json 的整段内容,点「解析并导入」。同时支持带 locks 数组的完整结构和单个凭证对象两种形式:
{
  "locks": [
    {
      "name": "宿舍门",
      "address": "AA:BB:CC:DD:EE:FF",
      "activationKey": "0123456789ABCDEF0123456789ABCDEF"
    }
  ]
}
  • 自动同步—— 补丁版天猫校园里点一次开锁后,钥匙会自动出现在列表里,不用手动导入; root 抓取则会把钥匙填进表单,确认后点「保存」。

凭证保存在本机 Android Keystore 的加密区。

第 3 步 · 开锁

回到首页,点卡片中间那个大按钮即可。首次会申请蓝牙权限,允许一次即可。

  • 冷启动首次开锁约 1.2 秒,60 秒内再次开锁约 0.4 秒;
  • 页面底部的「收发时序」会逐条显示收发字节,方便确认每一步都通了;
  • 「查电量」按钮可以顺便读门锁电量。

连接不是常驻的,按两条计时规则自动回收 —— 进入前台先自动预连接,30 秒内没有开锁就断开;一旦开锁则保活 60 秒,期间再开锁会重新计时;退到后台(含息屏)立即让出。这是有意为之:把门锁的并发连接让给真正要用的人,下次开锁会自动重新连上。首页顶部的状态角标(● 已预连接 / ◌ 预连接中 / ○ 未连接)可以直接看到当前状态。

抓不到凭证?按这个顺序排查

先确认一件事:天猫校园这次开锁到底有没有成功?门必须真的开了才有日志可抓,先别急着怀疑 TmallKey。

补丁版:回到 App 没看到门锁

现象检查
打开过门锁页,但列表里没有新锁只打开页面不够 —— 必须真的点一次「开锁」,钥匙才会传给原生层
点过开锁还是没有确认装的是补丁版(不是官方版);官方版没有同步模块
补丁版里开锁失败先在补丁版里把门打开一次(蓝牙权限、锁电量、距离都要正常)
切回 TmallKey 后要等几秒同步发生在 TmallKey 回到前台时,通常 1~3 秒内出现
饮水页提示没有登录态补丁版里重新登录一次(登录会重签校园会话),再回饮水页点导入

还是不行就把诊断信息发给开发者:

adb shell su -c "cat /data/data/com.fktm.app/files/water_diag.txt"   # 需 root
adb shell su -c "cat /data/data/com.tmall.campus.and/files/tmxydump_probe.log"  # 模块侧

电脑 adb 抓取

现象检查
adb devices 为空换线 / 换口;手机上确认「允许 USB 调试」弹窗
抓到的文件里没有 activationKey天猫校园必须先完成一次成功的开锁
有日志但没有钥匙行确认过滤标签里写了 VocLockHelperV2;天猫校园改版可能改了标签,先全量捞一次:adb logcat | findstr /i activationKey
verify 报缺少 pycryptodomepip install pycryptodome
都不行?换个时机再试一次。凭证抓取依赖天猫校园把日志打出来,不同版本、不同系统策略下差异很大 —— 但只要成功抓到过一次,之后就永久有效。
FAQ

常见问题

这和天猫校园是什么关系?会封号吗?

没有任何代码关系。它不调用天猫校园,也不读取它的进程,只是把 BLE 开锁报文按字节复刻了一遍。开锁时手机直接和门锁通信,服务器完全不知情。

「拿凭证」那一步只是趁天猫校园自己开锁时,把它已经下发给页面的钥匙取出来 —— 钥匙本来就是你自己的,只是原来没有别的地方能看到它。

换手机、重装系统之后还能用吗?

凭证存在本机 Keystore 加密区,不参与备份,卸载即销毁。换机请提前把 activationKey 抄下来(或在电脑端保留 credentials.json),在新机上重新导入即可。

为什么开锁不需要联网,但还是要蓝牙权限?

门锁是 BLE 蓝牙锁,手机就是通过蓝牙直接和它握手的。Android 12 及以上要「附近的设备」权限,12 以下要定位权限(系统限制,与 App 是否真的定位无关)。

为什么连上门锁之后过一会儿会自动断开?

这是有意为之。进入 App 会先自动预连接,30 秒内没有开锁就断开;一旦开锁则保活 60 秒,期间再开锁会重新计时;退到后台(含息屏)立即让出连接。

同一把锁可以被多台设备同时连,但并发会明显拖慢建连。让出连接是为了把门锁的并发让给真正要用的人,下次开锁会自动重新连上。

抓不到凭证怎么办?

先确认这次开锁真的成功了 —— 门真的开了才会有日志。手机端要注意 ColorOS 等系统会冻结后台进程,App 已经用前台服务 + 命中即落盘来兜底,但抓到后记得切回 App 让它读出来。

如果日志被 App 关掉了(比如官方升级后不再打印),就只能用 root + frida 那条备选路线了。

能开别人的门吗?

不能,也请不要尝试。activationKey 是服务端按门下发的,你只能拿到自己那扇门的。本项目仅供本人宿舍门使用。