目标接口
小红书搜索接口:POST /api/sns/web/v1/search/notes
关键请求头:X-S(签名值)、X-T(毫秒时间戳)、X-S-Common(设备指纹)
Jadx 静态分析
搜索字符串 "X-S" 定位到拦截器:
public class SignInterceptor implements Interceptor {
public Response intercept(Chain chain) throws IOException {
String ts = String.valueOf(System.currentTimeMillis());
String xs = XsGenerator.generate(
request.url().encodedPath(),
RequestBodyUtils.getBodyString(request), ts
);
return chain.proceed(request.newBuilder()
.header("X-S", xs).header("X-T", ts).build());
}
}
Native 层
public class XsGenerator {
static { System.loadLibrary("xhs-sign"); }
public static native String generate(String path, String body, String ts);
}
IDA 逆向后还原算法:MD5(path + body + ts + SALT) 加前缀 X1
Python 还原
import hashlib, time
XHS_SALT = 'YOUR_EXTRACTED_SALT'
def generate_xs(path, body=''):
ts = str(int(time.time() * 1000))
digest = hashlib.md5((path + body + ts + XHS_SALT).encode()).hexdigest()
return 'X1' + digest, ts
xs, xt = generate_xs('/api/sns/web/v1/search/notes', '{"keyword":"Python"}')
headers = {'X-S': xs, 'X-T': xt, 'X-S-Common': 'YOUR_DEVICE_FINGERPRINT'}
Frida 动态验证
Java.perform(function() {
var XsGenerator = Java.use('com.xingin.xhs.core.sign.XsGenerator');
XsGenerator.generate.implementation = function(path, body, ts) {
var result = this.generate(path, body, ts);
console.log(JSON.stringify({path, body, ts, result}));
return result;
};
});
对比 Frida 输出与 Python 还原结果,一致则完成。