抖音 App 签名算法 X-Gorgon、X-Khronos 解密 - Android 版

作者: Anoyi

2020-02-19 17:14

抖音APP 接口分析

1、安装「夜神模拟器」,并安装「抖音短视频」

2、安装「Charles」,配置并开启 SSL Proxy

Charles 免费激活码:https://zhile.io/2017/07/07/charles-proxy-usage-and-license.html

3、配置「夜神模拟器」网络代理

4、测试「Charles」抓包

打开「抖音短视频」,登录个人账号,访问其他用户,「Charles」会记录相关请求

如图所示,请求 Headers 中包含如下信息:

  • Accept-Encoding: 固定值「gzip」
  • X-SS-REQ-TICKET: 当前时间戳
  • sdk-version: 固定值「1」
  • Cookie: 个人登录信息,有效期很长
  • x-tt-token: 个人登录信息,固定值
  • X-Gorgon: 动态生成
  • X-Khronos: 动态生成
  • Host: 固定值
  • Connection:固定值「Keep-Alive」
  • User-Agent: 固定值「okhttp/3.10.0.1」

至此,基本的抓包流程走通。

X-Gorgon、X-Khronos 计算

1、反编译「抖音短视频」APK

反编译成功后,用关键词「X-Khronos」搜索全局代码,找到生成 「X-Khronos」的 Package Name、Method Name 和 Args。

2、逆向分析函数

使用相关逆向工具,动态代理签名函数,添加相关参数的日志打印逻辑。经分析,函数输入参数有两个:

  • URL:整个 API 请求地址
  • Headers:包含 cookieaccept-encodingsdk-versionuser-agentx-tt-tokenx-ss-req-ticket

3、编写测试代码

import sys
import time
import requests
from douyin_app.signature import sign

cookie = "***********"
accept_encoding = "gzip"
sdk_version = "1"
user_agent = "okhttp/3.10.0.1"
token = "************"

def get_user_info():
    """
    获取用户信息
    :return:
    """
    ts = str(int(time.time()))
    ticket = str(int(round(time.time() * 1000)))
    # 用户信息 sec_uid
    sec_user_id = 'MS4wLjABAAAAFS6CPjIHAim7TdTQjzevZX7LwfKCIi37PTVmqCpzdU0'
    # API 地址
    api = 'https://aweme-lq.snssdk.com/aweme/v1/user/?sec_user_id={}&address_book_access=1&retry_type=no_retry&iid=103707347463&device_id=70793717943&ac=wifi&channel=wandoujia_aweme2&aid=1128&app_name=aweme&version_code=790&version_name=7.9.0&device_platform=android&ssmix=a&device_type=R831T&device_brand=OPPO&language=zh&os_api=19&os_version=4.4.2&uuid=864394010882332&openudid=88E9FE8804850000&manifest_version_code=790&resolution=720*1280&dpi=240&update_version_code=7902&_rticket={}&mcc_mnc=46007&ts={}&app_type=normal'.format(sec_user_id, ticket, ts)
    headers = {
        "cookie": cookie,
        "accept-encoding": accept_encoding,
        "sdk-version": sdk_version,
        "user-agent": user_agent,
        "x-tt-token": token,
        "x-ss-req-ticket": ticket
    }
    x_gorgon, x_khronos = sign(api, headers)
    headers['X-Gorgon'] = x_gorgon
    headers['X-Khronos'] = x_khronos
    response = requests.get(api, headers=headers).json()
    return response

if __name__ == '__main__':
    get_user_info()
获取用户个人信息

至此,X-GorgonX-Khronos 计算流程跑通。

4、验证其他接口

def get_user_post():
    """
    获取用户视频列表
    :return:
    """
    ts = str(int(time.time()))
    ticket = str(int(round(time.time() * 1000)))

    # 用户 ID
    sec_user_id = 'MS4wLjABAAAAFS6CPjIHAim7TdTQjzevZX7LwfKCIi37PTVmqCpzdU0'
    # 分页索引,每页20,第二页输入 20
    cursor = 0

    # API 地址
    api = 'https://aweme-lq.snssdk.com/aweme/v1/aweme/post/?max_cursor={}&sec_user_id={}&count=20&retry_type=no_retry&iid=103707347463&device_id=70793717943&ac=wifi&channel=wandoujia_aweme2&aid=1128&app_name=aweme&version_code=790&version_name=7.9.0&device_platform=android&ssmix=a&device_type=R831T&device_brand=OPPO&language=zh&os_api=19&os_version=4.4.2&uuid=864394010882332&openudid=88E9FE8804850000&manifest_version_code=790&resolution=720*1280&dpi=240&update_version_code=7902&_rticket={}&mcc_mnc=46007&ts={}&app_type=normal'.format(str(cursor), sec_user_id, ticket, ts)
    headers = {
        "cookie": cookie,
        "accept-encoding": accept_encoding,
        "sdk-version": sdk_version,
        "user-agent": user_agent,
        "x-tt-token": token,
        "x-ss-req-ticket": ticket
    }
    x_gorgon, x_khronos = sign(api, headers)
    headers['X-Gorgon'] = x_gorgon
    headers['X-Khronos'] = x_khronos
    response = requests.get(api, headers=headers).json()
    return response
获取用户视频列表
def get_feed_list():
    """
    获取评论列表
    :return:
    """
    ts = str(int(time.time()))
    ticket = str(int(round(time.time() * 1000)))
    # 视频ID
    aweme_id = '6794011070555098380'
    # 分页索引,每页20,第二页输入 20
    cursor = 0
    # API 地址
    api = 'https://aweme-lq.snssdk.com/aweme/v2/comment/list/?aweme_id={}&cursor={}&count=20&insert_ids&address_book_access=1&gps_access=1&forward_page_type=1&openudid=88E9FE8804850000&version_name=7.9.0&ts={}&device_type=R831T&ssmix=a&iid=103707347463&app_type=normal&os_api=19&mcc_mnc=46007&device_id=70793717943&resolution=720*1280&device_brand=OPPO&aid=1128&manifest_version_code=790&app_name=aweme&_rticket={}&os_version=4.4.2&device_platform=android&version_code=790&update_version_code=7902&ac=wifi&dpi=240&uuid=864394010882332&language=zh&channel=wandoujia_aweme2'.format(aweme_id, str(cursor), ts, ticket)
    headers = {
        "cookie": cookie,
        "accept-encoding": accept_encoding,
        "sdk-version": sdk_version,
        "user-agent": user_agent,
        "x-tt-token": token,
        "x-ss-req-ticket": ticket
    }
    x_gorgon, x_khronos = sign(api, headers)
    headers['X-Gorgon'] = x_gorgon
    headers['X-Khronos'] = x_khronos
    response = requests.get(api, headers=headers).json()
    return response
获取视频评论列表

相关资料

看法

看法

昵称
邮箱