1. 接口分析
接口逆向基本原理及步骤:
- 找到参数的具体使用位置, 分析上下文逻辑
- 通过debug调试, 分析函数调用栈和参数值
- 拿出所需要的js代码进行复制生成逻辑
1.1 接口现象
快手获取数据的接口基本上都带有 **__NS__sig3
**这个加密参数, 而且每一次请求所携带的值不同

1.2 逆向分析
- 全局搜索
__NS_sig3
参数

- 在这里打上断点, 所用到的参数
e, t, a
传给m
函数, 处理完成之后调用s()
的$encode
方法将处理后的o
参数传递进去, 我们具体做的就是构造这个函数

- 找到m函数, 看到参数传递信息, 可以看到这三个参数也就是查询列表的参数,
e
为参数格式,t
为参数内容,a
为一个空对象(暂时不知道用处)

js
const e = "json";
const t = {
"queryType": "0",
"cursor": 1893456000000,
"startTime": 1710259200000,
"endTime": 1893456000000,
"limit": 30,
"timeRangeType": 5,
"keyword": "",
"kuaishou.web.cp.api_ph": "0505888108d7389715958a2bbf981069f05a"
};
const a = {};
m
函数调用p
和n
函数, 将参数做了进一步处理,p
函数对参数做了排序和encodeURI的操作,n()
函数则是一个标准的md5加密函数32位英文小写的结果



- 到这里我们就可以把用到的函数都copy下来放到js文件中, 运行一下, 比对o的值
js
import md5 from "md5";
function u(e, t = !0) {
return "object" !== typeof e
? []
: Object.keys(e).sort((e, a) => (e === a ? 0 : t ? (e > a ? 1 : -1) : e > a ? -1 : 1));
}
const p = e => u(e).reduce((t, a) => t + a + "=" + encodeURI(e[a]), "");
function m(e, t, a) {
let o = {
...a,
},
i = "";
switch (e) {
case "form-data":
o = {
...o,
...t,
};
break;
case "json":
i = `${JSON.stringify(t)}`;
break;
default:
break;
}
const s = p(o) + i;
return md5(s);
}
function sig() {
var e = "json";
var t = {
queryType: "0",
cursor: 1893456000000,
startTime: 1710259200000,
endTime: 1893456000000,
limit: 30,
timeRangeType: 5,
keyword: "",
"kuaishou.web.cp.api_ph": "0505888108d7389715958a2bbf981069f05a",
};
var a = {};
const o = m(e, t, a);
console.log("o ==> ", o);
}
sig();

- 目前就还剩下
s
函数, 查看函数调用栈, 在调用i
函数附近可以找到var i = a(75407)
的声明, 也就是这个a(75407)
函数就是我们要的s()


- 找到
a
函数的声明, 将文件copy下来, 此文件是一个典型的Webpack生成的manifest文件(运行时文件

- 在
a.m
对象中找到75407这个函数声明并复制下来

- 在webpack入口文件声明75407这个函数foo并将变量以全局变量形式导出, 方便后续使用

- 参数准备完毕, 开始调用函数, 没有报错, 导出sig函数准备测试
js
export function sig(e, t, a) {
const o = m(e, t, a);
console.log("o ==> ", o);
const bar = foo.n(foo(75407));
var res;
bar().call("$encode", [
o,
{
suc: function (t) {
res = t;
console.log("success", t);
},
err: function (e) {
console.log("error", e);
},
},
]);
return res;
}

- 增加网络请求工具测试,
t
请求数据中*kuaishou.web.cp.api_ph
*为快手登录时获取的token值
js
import axios from "axios";
import { sig } from "./foo.js";
const e = "json";
const t = {
queryType: "0",
cursor: 1893456000000,
startTime: 1710259200000,
endTime: 1893456000000,
limit: 30,
timeRangeType: 5,
keyword: "",
"kuaishou.web.cp.api_ph": "0505888108d7389715958a2bbf981069f05a",
};
const a = {};
const url =
"https://cp.kuaishou.com/rest/cp/works/v2/video/pc/photo/list?__NS_sig3=" + sig(e, t, a);
console.log("url => ", url);
const headers = {
Cookie:
"didv=1730444336345; ...",
};
const data = t;
axios
.post(url, data, { headers })
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});

总结
快手在请求数据接口时, 所携带的 __NS__sig3
参数是由具体请求参数进行排序, md5加密并进行encode处理后的值