H1karu 发表于 2021-10-8 19:55

小米小爱音响登录算法

# 小米小爱音响登录
- 登录分为两部分,QQ互联和小米账号。QQ互联要求小米账号绑定QQ。小米账号无法异地登陆
## QQ互联部分
- GET访问 `https://account.xiaomi.com/pass/sns/login/auth?appid=100284651&&callback=https://api2.mina.mi.com/sts&sid=micoapi`,取回 Cookie,需要得到 `state`、`tick`
- GET访问 `https://ssl.ptlogin2.qq.com/ptqrshow?appid=716027609&e=2&l=M&s=3&d=72&v=4&t=0.495234860855095&daid=383&pt_3rd_aid=100284651`,取回登录二维码和 Cookie 备用
- 运行 JavaScript`
    function hash(t) {
      for (var e = 0, i = 0, n = t.length; i < n; ++i)
            e += (e << 5) + t.charCodeAt(i);
            return 2147483647 & e
      }
` 传入参数为登录二维码返回的 `qrsig`,返回值作为 `ptqrtoken` 备用

- GET访问 `https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://graph.qq.com/oauth2.0/login_jump&ptqrtoken= + ptqrtoken + &ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-3-1619441958523&js_ver=20010217&js_type=1&pt_uistyle=40&aid=716027609&daid=383&pt_3rd_aid=100284651&ptdrvs=&has_onekey=1&`,注意替换 `ptqrtoken`,这里需要实时记录返回值
- 这里需要加一个循环实时判断返回值,取返回值的 `ptuiCB` 判断状态,`66` 为二维码有效,`65` 为失效、`67` 为已扫描。如果返回值包含 `https://ssl.ptlogin2.graph.qq.com/check_sig?pttype=1&uin=` 则是登陆成功
- GET访问 `https://ssl.ptlogin2.graph.qq.com/check_sig?pttype=1&uin=` + 返回值中的 `&uin=` 到 `&pt_aaid` 字段 + `&pt_aaid=16&pt_light=0&pt_3rd_aid=100284651`,记录返回 Cookie
- 从 Cookie 里提取到 `p_skey`、`p_uin`、`pt4_token`、`uin (p_uin 的长度 -1)`
- GET访问 `https://graph.qq.com/oauth2.0/login_jump`,Cookie 分别带上之前的 `p_skey`、`p_uin`、`pt4_token`、`uin`
- 运行 JavaScript
`
function g_tk(str) {
      hash = 5381;
      for (var i = 0, len = str.length; i < len; ++i) {
          hash += (hash << 5) + str.charCodeAt(i);
      }
      return hash & 0x7fffffff;
      }
`,传入 p_skey
- POST访问 `https://graph.qq.com/oauth2.0/authorize`,参数带之前获取到的所有内容
- 最后跳到 米家API 取得 `nonce`、`ssecurity`、`userId`、`cUserId`、`passToken`、`tick`、`JSESSIONID`
- 计算 `clientSign` 为 "`nonce=` + nonce + `&` + ssecurity" 的 16进制 SHA1编码 (逆向 APK 取得)
- 把 `clientSign` URL编码、BASE64编码后作为参数提交到返回值 `location` 的地址获取 `serviceToken`

## 米家 API 部分
- 和 QQ登录 的最后几步一样,只是登陆部分不同
- POST访问 `https://account.xiaomi.com/pass/serviceLoginAuth2?_json=true&sid=micoapi&locale=zh_CN&user=` + 用户名 (不是手机号) + `&hash=` + 密码的大写MD5值,记录返回值(抓包获得)
- 解析返回的 JSON,如果 `Code` 为 `0` 则是登录成功
- 分别记录返回值的 `ssecurity`、`passToken`、`nonce`、`userId`、`cUserId`、`location`、`psecurity`
- 计算 `clientSign` 为 "`nonce=` + nonce + `&` + ssecurity" 的 16进制 SHA1编码 (逆向 APK 取得)
- 把 `clientSign` URL编码、BASE64编码后作为参数提交到返回值 `location` 的地址获取 `serviceToken`

## 说明
- 最终目的就是取得 `serviceToken`,QQ互联登录可能稍微复杂,都是抓包取得的。返回的标准JSON格式直接解析即可,最终返回的 `serviceToken` 配合前面的 `ssecurity`、`passToken`、`nonce`、`userId`、`cUserId`、`location`、`psecurity` 组成 Cookie 即可任意调用 API
- 没什么技术含量,都是抓包可得的

A021 发表于 2021-11-2 12:27

之前由于XM社区内测分调整的原因,做过一个自动做内测任务的,其中,社区app登录,需要传入一个clientSign值,我在网上也看见过其他贴说是"nonce= + nonce + & + ssecurity" 的 16进制 SHA1编码,问一下这里的ssecurity,是变量名还是变量值,我曾经写的是变量值,仍然登录不成功,那时候因为这一个值,就此放弃了。

hiodis 发表于 2022-1-6 15:43

不错 学习

小左a 发表于 2022-1-29 20:56

请问怎么取到音响的对话内容

三滑稽甲苯 发表于 2022-2-12 20:26

能详细说说米家API后两步吗,我最后那个请求get到的总是空

三滑稽甲苯 发表于 2022-2-12 20:31

感谢,最后在 https://github.com/syjjx/miai/blob/master/hello_miai.py#L190 的代码里完成了脚本

cafechan 发表于 2024-3-26 13:41

感谢分享,折腾不止
页: [1]
查看完整版本: 小米小爱音响登录算法