ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Xiaomi Cloud Tokens Extractor 完整指南:一键提取小米云设备 Token 与 BLE 加密密钥

Xiaomi Cloud Tokens Extractor 完整指南:一键提取小米云设备 Token 与 BLE 加密密钥
  • 物联网
  • 开发工具

【免费下载链接】Xiaomi-cloud-tokens-extractor

This tool retrieves tokens for all devices connected to Xiaomi cloud and encryption keys for BLE devices.

项目地址:https://gitcode.com/gh_mirrors/xia/Xiaomi-cloud-tokens-extractor
点击查看免费下载

导读:本文基于开源仓库 Xiaomi Cloud Tokens Extractor(README.md)编写,围绕"登录小米云 → 选择服务器区域 → 提取全部设备 Token 与 BLE 加密密钥"这一核心链路展开。读完你将掌握 Windows / Linux / Docker / Python 四种运行方式、用户名密码与二维码两种认证流程、全部命令行参数的含义与用法、设备信息输出的字段结构与 JSON 格式,以及常见登录故障的排查方法,为后续将米家设备接入 Home Assistant 等本地平台做好准备。

一、工具定位:能做什么、解决什么问题

按照项目 README.md 的定义,这个工具的核心能力只有一句话:检索连接到小米云的所有设备的 Token,以及 BLE(蓝牙低功耗)设备的加密密钥("This tool retrieves tokens for all devices connected to Xiaomi cloud and encryption keys for BLE devices.")。

在实践中的典型应用场景是:

  • 米家 App 内不提供设备 Token 的导出入口,而将米家设备接入 Home Assistant 等本地智能家居平台时,往往需要设备的token才能建立本地通信;
  • 部分 BLE 设备(如传感器、门锁等)还需要beaconkey这类加密密钥才能解密其蓝牙广播数据。

该工具通过模拟小米账号登录流程,把账号下所有设备及其 Token、IP、MAC、型号等信息一次性拉取出来,省去了逐个设备抓包或依赖第三方云的麻烦。

它支持两种认证方式(token_extractor.py 与 README 中均有说明):

认证方式说明
用户名 + 密码用户名支持邮箱、手机号或小米云账号 ID,密码交互输入时不会回显
二维码通过扫码完成授权,适合密码/验证码流程受阻的场景

登录成功后,需要选择小米服务器的区域(cn代表中国、de代表德国等),留空则会依次遍历所有可用区域。作为返回结果,账号下连接的全部设备都会被列出,并附带设备名称与 IP 地址等信息。

二、支持的服务器区域

工具内置的服务器区域列表定义在源码 token_extractor.py 中:

SERVERS = ["cn", "de", "us", "ru", "tw", "sg", "in", "i2"]

对应关系如下(区域代码是小米云实际使用的 API 前缀,并非自定义):

区域代码含义
cn中国
de德国
us美国
ru俄罗斯
tw台湾
sg新加坡
in印度
i2其他地区(国际版等)

在交互模式下,程序会提示输入服务器(提示语为Select server (one of: ...; Leave empty to check all available)),输入空值即表示"检查全部可用区域";输入非法值会循环重新提示,直到得到合法输入为止(见 get_servers_to_check)。

三、四种运行方式

3.1 Windows:直接运行可执行文件

Windows 用户无需安装 Python 环境,直接下载对应发行版中的token_extractor.exe并运行即可。该可执行文件由 PyInstaller 打包生成,打包配置见仓库根目录的 token_extractor.spec:它把 token_extractor.py 编译为名为token_extractor的控制台程序(console=True),并附带 icon.ico 作为图标。

3.2 Linux 与 Home Assistant(SSH & Web Terminal)

在 Linux 或 Home Assistant 的 SSH & Web Terminal 插件中,直接执行仓库根目录的一键脚本:

bash run.sh

该脚本(run.sh)的实际动作包括:探测 Home Assistant 主机的 IP 地址并作为--host参数传入 → 下载发布包 zip → 解压 → 安装requirements.txt依赖 → 以python3 token_extractor.py --host <HA主机IP>运行 → 结束后清理临时文件。

--host参数的作用是让二维码/验证码图片在浏览器中的访问地址指向 HA 主机而非127.0.0.1,方便从局域网内其他设备打开查看(详见后文"图片展示机制")。

3.3 Docker 与 Home Assistant

如果上面的脚本安装失败,官方建议改用 Docker 版本:

bash run_docker.sh

run_docker.sh 会下载 Docker 版发布包、基于仓库内的 Dockerfile 构建镜像并运行容器。镜像基于python:3-alpine构建,安装build-base编译依赖后执行pip3 install --no-cache-dir -r requirements.txt,容器入口为python ./token_extractor.py,并映射了31415端口(用于图片展示服务)。

在 Home Assistant 中运行该命令有一个前提:必须在插件设置中关闭protected mode(保护模式)并重启插件,否则脚本无法正常访问网络或执行系统调用。

3.4 Python 手动运行

需要自己动手的场景(例如想直接阅读源码或二次开发)可以手动安装运行:

git clone https://gitcode.com/gh_mirrors/xia/Xiaomi-cloud-tokens-extractor cd Xiaomi-cloud-tokens-extractor pip3 install -r requirements.txt python3 token_extractor.py

依赖清单(requirements.txt)及其在代码中的实际用途如下:

依赖包源码中的用途
requests发起小米账号登录与云 API 请求(token_extractor.py)
pycryptodome提供 RC4(ARC4)加解密算法,用于云 API 的密文通信(token_extractor.py)
charset-normalizerrequests 依赖的字符集检测库,保证响应文本正确解码
Pillow显示验证码 / 二维码图片(token_extractor.py)
colorama终端彩色日志输出(token_extractor.py)

四、命令行参数详解

工具通过argparse解析命令行参数(token_extractor.py),完整参数如下:

参数简写含义默认值 / 取值范围
--non_interactive-ni非交互模式,全程不弹出提示布尔开关
--username-u用户名(邮箱 / 手机号 / 小米账号 ID)无
--password-p密码无
--server-s指定服务器区域cn/de/us/ru/tw/sg/in/i2/ 空
--log_level-l日志级别默认CRITICAL;可选CRITICAL、FATAL、ERROR、WARN、WARNING、INFO、DEBUG、NOTSET
--output-o将结果写入指定 JSON 文件无
--host无图片服务的对外主机地址默认127.0.0.1

几点关键行为需要特别注意:

  1. 非交互模式的强制约束:使用--non_interactive时必须同时提供--username和--password,否则程序会直接报错退出(token_extractor.py):
    You need to specify username and password or run as interactive.
  2. 非交互模式会跳过交互式提示:所有print_if_interactive()的输出都会被抑制;验证码、2FA 邮件验证码等需要人工参与的场景在非交互模式下会直接报错并要求改为交互模式运行(见 handle_captcha 与 do_2fa_email_flow)。
  3. 非交互模式下服务器默认遍历全部:未指定--server时,get_servers_to_check()会返回完整的 8 个区域逐一检查(token_extractor.py)。
  4. 日志级别默认CRITICAL:即默认只输出严重错误,排查问题时建议加上--log_level DEBUG观察详细请求与响应过程。日志通过ColorLogger输出到 stdout,并按级别着色(token_extractor.py)。

一个完整的非交互式调用示例:

python3 token_extractor.py \ --non_interactive \ --username "your@email.com" \ --password "your_password" \ --server cn \ --output devices.json \ --log_level INFO

五、交互式运行流程

以交互模式启动后,程序依次执行(入口见 main):

  1. 打印 ASCII 艺术横幅(Xiaomi Cloud Tokens Extractor by Piotr Machowski);
  2. 提示选择登录方式,输入p使用密码登录、q使用二维码登录(输入其他字符会一直循环询问);
  3. 执行对应的登录流程;
  4. 登录成功后提示选择服务器区域(留空 = 检查全部区域);
  5. 依次遍历服务器 → 家庭 → 设备,打印设备信息;
  6. 交互模式下最后会等待按下 ENTER 才退出。

六、密码登录流程(源码级)

密码登录由PasswordXiaomiCloudConnector实现(token_extractor.py),整体分三步:

  • 第一步login_step_1:请求https://account.xiaomi.com/pass/serviceLogin?sid=xiaomiio&_json=true获取_sign(签名),为下一步提交凭据做准备(token_extractor.py)。
  • 第二步login_step_2:向serviceLoginAuth2提交用户名、密码的MD5 大写哈希(hashlib.md5(...).hexdigest().upper())、_sign等字段完成认证(token_extractor.py)。这一环节可能触发两类人工验证:
    • 图形验证码(captcha):响应中出现captchaUrl时,程序会下载验证码图片并展示,要求用户输入图中字符(区分大小写)。交互模式下可用;非交互模式会直接报错提示改为交互模式(handle_captcha)。
    • 邮箱二次验证(2FA):响应中出现notificationUrl时,程序会自动走identity/list→sendEmailTicket→ 输入邮箱收到的验证码 →verifyEmail→identity/result/check→Auth2/end的完整 2FA 邮件流程,最终从响应头extension-pragma中解析出ssecurity,并从 STS 跳转后携带的 Cookie 中取得serviceToken(do_2fa_email_flow)。
  • 第三步login_step_3:访问上一步返回的location跳转地址,从响应 Cookie 中取得serviceToken(token_extractor.py)。

密码登录成功的标志是取得ssecurity、userId、serviceToken三样凭据,后续所有云 API 调用都以它们为基础。

七、二维码登录流程(源码级)

二维码登录由QrCodeXiaomiCloudConnector实现(token_extractor.py),分为四步:

  1. login_step_1:请求https://account.xiaomi.com/longPolling/loginUrl获取二维码图片地址、登录 URL 与长轮询(long polling)地址;
  2. login_step_2:下载二维码图片并展示,同时打印可访问的登录 URL(供无法扫码时手动打开);
  3. login_step_3:对长轮询地址发起轮询(每次请求超时 10 秒,总超时由服务端返回的timeout字段决定),等待手机扫码确认后,从响应中解析出userId、ssecurity、passToken等凭据;
  4. login_step_4:访问location地址取得serviceToken。

图片展示机制与--host参数

无论是二维码还是验证码,程序都通过present_image_image()来展示图片(token_extractor.py),其策略为:

  1. 优先在本机31415端口启动一个临时 HTTP 服务(start_image_server,见 token_extractor.py),并打印形如http://<host>:31415的访问地址,用户可在浏览器中打开查看图片;
  2. 若启动失败(例如端口被占用),则把图片保存为临时.jpg文件并尝试调用系统图片查看器打开;仍失败则打印文件路径让用户手动打开。

--host参数正是在这里发挥作用:它决定打印出来的访问地址用哪个 IP(token_extractor.py)。在 Home Assistant 场景下,run.sh/run_docker.sh会自动探测 HA 主机的 IP 并传入,方便你用局域网内的手机或另一台电脑打开二维码页面。

八、登录后的设备信息提取流程

登录成功后,主程序按"服务器 → 家庭(home)→ 设备"的层级遍历账号下的所有资源(main):

  1. 列出家庭:调用get_homes(country)请求/v2/homeroom/gethome,拿到账号拥有的家庭列表;同时调用get_dev_cnt(country)请求/v2/user/get_device_cnt,补充共享家庭(share_family)信息(token_extractor.py)。
  2. 列出设备:对每个家庭调用get_devices(country, home_id, owner_id)请求/v2/home/home_device_list,拿到该家庭下全部设备(token_extractor.py)。
  3. 提取 BLE 密钥:对设备 ID 以blt开头的 BLE 设备,额外调用get_beaconkey(country, did)请求/v2/device/blt_get_beaconkey获取beaconkey,即 README 中所说的"BLE 设备的加密密钥"(token_extractor.py)。

控制台输出字段

每个设备会打印如下字段(token_extractor.py):

字段含义来源
NAME设备名称云 API 返回的name
ID设备 ID(did),BLE 设备以blt开头云 API 返回的did
BLE KEYBLE 设备专属的加密密钥get_beaconkey返回的beaconkey
MAC设备 MAC 地址云 API 返回的mac
IP设备局域网 IP 地址云 API 返回的localip
TOKEN设备 Token(接入 Home Assistant 等本地平台的核心凭据)云 API 返回的token
MODEL设备型号云 API 返回的model

这正是 README 所说"所有设备连同名称和 IP 地址一起列出"的完整落地实现。

-o输出 JSON 结构

配合--output devices.json可以把结果写入文件,顶层结构如下(token_extractor.py):

[ { "server": "cn", "homes": [ { "home_id": 123456, "home_owner": "用户名ID", "devices": [ { "name": "客厅台灯", "did": "123456789", "mac": "AA:BB:CC:DD:EE:FF", "localip": "192.168.1.100", "token": "xxxxxxxxxxxxxxxx", "model": "yeelink.light.lamp1", "BLE_DATA": { "beaconkey": "..." } } ] } ] } ]

其中 BLE 设备(did以blt开头)会额外包含BLE_DATA对象。

九、底层协议细节(进阶阅读)

理解底层实现有助于排查问题,也能帮你判断哪些日志信息是有意义的。

API 地址规则

不同区域的 API 主机名由get_api_url(country)动态拼接(token_extractor.py):

return "https://" + ("" if country == "cn" else (country + ".")) + "api.io.mi.com/app"

即中国区为https://api.io.mi.com/app,德国区为https://de.api.io.mi.com/app,其余区域依此类推。

请求加密流程

每次云 API 调用都走execute_api_call_encrypted()(token_extractor.py),请求头带有MIOT-ENCRYPT-ALGORITHM: ENCRYPT-RC4、x-xiaomi-protocal-flag-cli: PROTOCAL-HTTP2等标记,整体链路为:

  1. 基于当前时间戳生成nonce(8 字节随机数 + 分钟级时间戳,Base64 编码,见 generate_nonce);
  2. 用ssecurity与nonce做 SHA-256 得到signed_nonce(signed_nonce);
  3. 对请求参数计算 HMAC-SHA256 签名与 SHA-1 加密签名(generate_signature、generate_enc_signature);
  4. 用 RC4 加密请求参数,附上signature、ssecurity、_nonce后 POST 出去(generate_enc_params);
  5. 收到响应后用 RC4 解密(注意 RC4 使用前会先丢弃前 1024 字节,见 encrypt_rc4 / decrypt_rc4)。

这些细节意味着:工具运行时打印的"登录成功 / 无法登录 / 无法获取设备"等信息,背后对应的是上述多步加解密与签名流程,任何一步的服务端校验失败都会导致失败。

十、故障排查(Troubleshooting)

README 明确给出以下排查清单,建议按顺序逐项尝试:

  1. 确认凭据正确:务必使用小米账号(邮箱 / 手机号 / 小米云账号 ID)对应的用户名密码,不要使用来自 Roborock(石头)App 等第三方 App 的登录凭据——它们往往无法通过小米账号体系认证。
  2. 移除 Cloudflare DNS:Cloudflare 的 DNS 解析可能干扰小米登录域名的连接,导致握手或请求失败。
  3. 关闭网络广告拦截与限制:AdGuard、PiHole 等广告拦截工具,以及 UniFi Country Restriction(地区限制)等网络策略,都可能阻断小米账号服务,需要临时禁用。
  4. 检查 2FA 邮件的垃圾箱:邮箱二次验证码邮件可能被误判为垃圾邮件,请到 SPAM 文件夹查找。
  5. 改用二维码认证:密码登录多次受阻时,优先切换到q(二维码)方式,绕开密码哈希与验证码链路。
  6. 耐心等待:小米账号服务存在每日 2FA 请求次数限制(视区域不同为 3 次或 5 次),超出限制后当天无法继续触发验证,只能等待额度恢复。

十一、Home Assistant 生态扩展

项目作者还提供了与本文主题强相关的两个配套工具(README 的"Home Assistant additional tools"一节),可用于将提取到的数据进一步落地使用:

  • Map extractor(小米云地图提取器):为小米扫地机器人提供实时地图显示的自定义组件,配合本工具拿到的 Token 使用;
  • Map card(扫地机地图卡片):一个 Lovelace 卡片,支持从 Lovelace 界面手动控制扫地机器人。

两者与本文主题的关系是:本文提取的 Token 是这类自定义组件接入米家设备的必要前置条件——先用本文介绍的工具拿到 Token,再配置对应的集成组件。

十二、安全与使用须知

  • 工具在本地完成全部登录与请求过程,凭据不会上传到任何第三方服务,但请妥善保管输出文件(尤其是-o导出的 JSON,内含 Token 与 BLE 密钥);
  • 设备 Token 属于敏感凭据,泄漏后他人可能获得设备的本地控制权限,请勿将其提交到公开仓库或公开分享;
  • 工具基于小米云官方接口的私有协议实现,小米可能调整接口行为;若遇异常,优先参考上文"故障排查"清单,并将日志级别调至DEBUG观察具体失败环节。

总结:Xiaomi Cloud Tokens Extractor 通过模拟小米账号登录(密码 / 二维码)获取ssecurity与serviceToken,再借助带 RC4 加密与签名机制的云 API 遍历服务器、家庭、设备三层结构,最终输出每个设备的NAME、ID、MAC、IP、TOKEN、MODEL,并为 BLE 设备额外抓取beaconkey。无论是 Home Assistant 玩家、智能家居开发者,还是需要批量管理米家设备的自动化场景,它都是一把开箱即用的"钥匙"。

  • 物联网
  • 开发工具

【免费下载链接】Xiaomi-cloud-tokens-extractor

This tool retrieves tokens for all devices connected to Xiaomi cloud and encryption keys for BLE devices.

项目地址:https://gitcode.com/gh_mirrors/xia/Xiaomi-cloud-tokens-extractor
点击查看免费下载
上一篇:终极窗口控制指南:SRWE实时窗口编辑器完整教程
下一篇:如何在Photoshop中免费开启WebP格式支持:WebPShop插件完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进