目标接口

小红书搜索接口: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 还原结果,一致则完成。