抖音做爲一款日活超過1億的優秀APP,其客戶端與服務端的通訊方式很值得APP開發者去研究和學習,爲了保護其數據,客戶端請求數據的接口都進行了加密,未通過加密處理的url,請求的時候不會返回數據,這裏以最新的3.0版本爲例,分析一下加密算法。java
https://api.amemv.com/aweme/v1/feed/?manifest_version_code=310&_rticket=1541061729354&pull_type=2&app_type=normal&iid=48910484145&channel=aweGW&device_type=Redmi+5A&language=zh&type=0&uuid=868661038685020&resolution=720*1280&openudid=7664f169100e4e94&update_version_code=3102&os_api=25&max_cursor=0&filter_warn=0&need_relieve_aweme=0&dpi=320&ac=wifi&device_id=58329658832&os_version=7.1.2&count=6&version_code=310&is_cold_start=0&volume=0.0&app_name=aweme&req_from=&version_name=3.1.0&js_sdk_version=&device_brand=Xiaomi&ssmix=a&device_platform=android&min_cursor=-1&aid=1128&ts=1541061729&as=a1e58b7dd1960b1c1a4355&cp=bc64b9541ca0d2c8e1cDgM&mas=01b9fcc9ce21a0deb29046deb46e30350aacaccc2c868cc68c460c
android
上面的url用於抖音首頁推薦列表數據的請求,能夠看到除了一些設備、網絡、渠道等相關信息之外,url尾部有as、cp和mas三個參數,這三個參數用於加密url,它們是根據前面的參數計算出來的。咱們先看一下Java部分:c++
大概的計算流程以下:UserInfo.getUserInfo(ts, (String[]) list.toArray(new String[list.size()]), null, device_id)
獲取一個44位加密後的字符串, 第1個參數是時間戳,第2個參數是第1步的list轉換成的數組,第4個參數是第2步獲取的device_id;這個方法是在native中實現;Lcom/ss/sys/ces/f/a;->a(as.getBytes())[B
獲取一個27位的byte數組,最終會調到Lcom/ss/sys/ces/a;->e([B)[B
,這個方法也是native實現;Lcom/ss/android/common/applog/k;->a([B)Ljava/lang/String;
,結果爲54位的字符串,賦值給mas,k.a()的實現以下圖,走最後一個else分支;
能夠看到抖音url加密算法的核心部分採用c/c++語言來實現,對native部分的逆向分析比java部分難度更大,並且抖音增長了反調試技術而且對native函數的名字進行了混淆,對代碼邏輯進行ollvm混淆,進一步增長了分析的難度;經過分析,咱們發現抖音的加密算法在libcms.so中,利用IDA靜態分析加上inline hook技術,咱們找到了getUserInfo的native實現函數sub_26750(0x26750是函數的相對so文件起始位置的偏移): git
Lcom/ss/sys/ces/a;->e([B)[B
的native實現函數是sub_2f1c8()
native部分的具體細節這裏不在列出,你們能夠參考看雪論壇上的兩篇文章:github
最後,對抖音API加密算法感興趣的朋友,能夠聯繫我。 其餘APP API簽名算法分析能夠參考下面的文章:算法