小程序下单接口有 X-Ca-Signature/X-Ca-Nonce/X-Ca-Timestamp,反编译找不到生成逻辑,求思路 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
fire2y
V2EX    程序员

小程序下单接口有 X-Ca-Signature/X-Ca-Nonce/X-Ca-Timestamp,反编译找不到生成逻辑,求思路

  •  
  •   fire2y 87 天前 2069 次点击
    这是一个创建于 87 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近一直在和喜欢的妹子打羽毛球,每次周末抢不到体育馆场地,想写脚本来抢。
    我用 wxapkg 把本地小程序解包,看到了反编译代码;用 Charles 抓包发现下单接口请求头有 X-Ca-Signature 、X-Ca-Nonce 、X-Ca-Timestamp ,如果这几个头不对就会 401 。
    问题是:在反编译的代码里找不到这几个请求头是怎么生成的,Charles 里也没有看到其他接口会返回这三个值(也没找到生成签名的接口)。我尝试用 Claude 分析,它只做了关键字匹配,判断这是阿里的接口,但仍在 Charles 里找不到相关请求。
    大家有什么思路?是我没完全解密前端,还是小程序有特殊机制在生成这几个头?
    18 条回复    2025-09-26 09:54:41 +08:00
    Vegetable
        1
    Vegetable  
       87 天前
    时间戳、Nonce 、Signature 这三个字段是常见的签名字段。正常来说,前端会有一段逻辑,根据该请求的业务请求参数、当前时间、随机生成的 Nonce 作为输入,来生成一个签名,并将这三个东西和其他请求参数一起发送给后端。

    所以,如你所想,这三个参数是在前端生成的。时间戳就是时间戳,确保请求有一定时效性。Signature 就是签名结果,Nonce 是 Number used Once ,可以起到防重放作用(时间戳有效的窗口内,所有使用过的 Nonce 都记录下来)

    这些参数通常不会和微信有什么关系,至少我没见过微信提供这些东西,都是前后端约定的。你可以终点在代码里搜索一些哈希操作 Crypto 库之类的,只有这些信息很难提出什么建设性意见。
    fire2y
        2
    fire2y  
    OP
       87 天前
    @Vegetable 我在代码里面能找到有 Crypto 库之类库 我怀疑是这部分的代码完全被混淆了 在一个大的文件里面 有 1w 多行 我关键字搜索能搜索到 结论应该就是前端生成的 只是被混淆了 我还是有机会破解出来 如果是小程序的机制 我就直接放弃了
    microBlock
        3
    microBlock  
       87 天前
    叫啥小程序,我可以帮你逆向看看
    fire2y
        4
    fire2y  
    OP
       87 天前
    @microBlock 川沙体育中心 curl -H "Host: shop.chuanshatiyuchang.cn" -H "X-Ca-Signature: Cr6EfMOwHP3q4oGCXMPXfj2rxiWUR0usg0CBsmnJY+P8ZmDmqrhdnf/4HeNxVwiFpk8NtSHxfX5SJc0RS/dfjbm0Javmqev+3ADWMqOe65nYIyxib5csEphHCa/JgYlZXwkzXDLz0lf06LqjtfToVjk2hilOjPKKrQbgx8HsPF9MbhKBJtyrDNul4pvOxIfiGSSk8+CVfdXlWDXQJnOPiSa7tyUty9l6/q0FZqSXDB97UYQKOlbxUmksGA4A2HcZuVzYo5ivgwDW6ib57PywNtSHoVBefktP2BZmaYz57SHcBh+69X6mb6DWwq0B8sWIkOdrcWcbPRVOm1Qre6ChkQ==" -H "X-Ca-Nonce: icp62g" -H "X-Ca-Timestamp: 1758707658" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 MicroMessenger/6.8.0(0x16080000) NetType/WIFI MiniProgramEnv/Mac MacWechat/WMPF MacWechat/3.8.10(0x13080a10) XWEB/1227" -H "token-user: xxxxxxx" -H "x-gym-client-id: 1" -H "Content-Type: application/json" -H "xweb_xhr: 1" -H "Accept: */*" -H "Sec-Fetch-Site: cross-site" -H "Sec-Fetch-Mode: cors" -H "Sec-Fetch-Dest: empty" -H "Referer: https://servicewechat.com/wx2fdf924861911ddc/15/page-frame.html" -H "Accept-Language: zh-CN,zh;q=0.9" --data-binary "{\"venueSportId\":1,\"areaItems\":[{\"areaDate\":\"2025-09-25\",\"areaId\":43,\"areaName\":\"三号场(3F)\",\"endTime\":\"11:00\",\"packageId\":null,\"price\":\"35\",\"showStatus\":\"AVAILABLE\",\"sportId\":1,\"sportName\":\"羽毛球\",\"startTime\":\"10:00\",\"status\":\"NORMAL\",\"uniqNo\":\"43_20250925_10:00_11:00\",\"checked\":true,\"row\":2,\"col\":1},{\"areaDate\":\"2025-09-25\",\"areaId\":43,\"areaName\":\"三号场(3F)\",\"endTime\":\"12:00\",\"packageId\":null,\"price\":\"35\",\"showStatus\":\"AVAILABLE\",\"sportId\":1,\"sportName\":\"羽毛球\",\"startTime\":\"11:00\",\"status\":\"NORMAL\",\"uniqNo\":\"43_20250925_11:00_12:00\",\"checked\":true,\"row\":2,\"col\":2}]}" --compressed "https://shop.chuanshatiyuchang.cn/gym/miniprogram/areaOrder/createOrder" 这个是具体的那个接口
    microBlock
        5
    microBlock  
       87 天前   1
    找到了
    microBlock
        6
    microBlock  
       87 天前   1
    // 引入 jsrsasign 库
    const jsrsasign = require('jsrsasign');


    const RSA_SIGN_KEY = "-----BEGIN PRIVATE KEY-----
    MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDPi4B6DrHEMpDA
    8t9VOCkB2/mKEeSwQxdKwTks9HuZiG0nMxJ4Uj1cRrBHjr+9GB8ZyUFeZE+muVnj
    ql9OeymWNlgWcISpFu6S49gT56RnMlXQCTKFMfhXfFsXQ7GiioeUIq6HmLOtvuX5
    StK7TwodAxzQQpjUx0XIHmRKk2XHgktZlD0B3LuvAO7Y73fkwR/Kp3vXTnJShiSt
    XbHTdC7GSXCvqglfGN5jyigmHqwgC1di+QGILPLJEDXpoAYtmcWWzs182ALShde9
    sBR0BV6+DWCyeVzBEIwQKo+azdqmsdQkD1mXZj33iuVNJ+WcEg/D8i4byx5uouDU
    dFvbuMNZAgMBAAECggEABP9vfcD1KpaAd4esYBwk71IG7XpmfuYcB/qk2qkdLC0l
    r8AiQuUmwXOZqBzPD4nRVJN3mwMgYJFDEbaXFUflpaPeYCqfzzCUWH4wbwjwzmQJ
    vqOSD19iLb0lYRHfaQdxTLG/G9h4rzI9zdCC8uwW1WxZ7nFEG+TxOxNG8qgfrHuy
    zkihcWYDmmmoLqMg5CBi8QBWfkohegox3vOjAbX3OKjnWUf7aSiuIlZrXy9mEgqd
    zQhsDDHGje0MqpkS6o9Y362LI8CD69K03NyLRc5FnlzWD5R21w7hlOWAN+/WIQWl
    7uVMI/B5lMbsJ8t6nrZk46bFVqSSiqdY6XHXNUJdGQKBgQDsXKgoigXcVXlcVvzD
    CMn7UkVCjwXpBXLMS4VXheWLGP2hLxBSZeOXdJ4hknkn/zKFv1X6/3VoLnJnYMm6
    yyerpsTRhUM+jwkOF4/EgM/pOBc9RVOmmLWAUFy0mdabnBvK2Rvt+qSyZepYvcc1
    GGvPg2ssKXjBaAbx/xFpx6kTzQKBgQDgyeqVUKULrEU2KQ8JAbdT0+ht5mT2LDn+
    W2HjuPlcHtNI1co9UUZ6byZXXoE4TZ1W0cAaTiHpw3o2hDql9YfZQ7NWdhwNO1sm
    /eYcJa1R8xyKlKtVnCPlzOA/gVJmSv50e1WNvzUsTwLHwoHZVX9UjGPqw5d2pVpj
    ViuNTO65vQKBgQDWxBZzx34tx2ifs9a17N2CxC10nfpz0mSOJy0A6wQ40Ltc4yPE
    ixoyu18YCDyYUDT6/HFGwSpQQKvpLTP/y6q/OKhr7Ne+Fz/WEyiqF5VTR4kuPjkV
    DnsVHXAvFf2/pShHt+C961oNU7eNbNt+bjM/+hy+ouw7aKeu6eJLqIUEHQKBgGST
    k4VJdv9ZDgKkrlh+TxOPzgBWRLgso6oeIxdr7Q59sFV3aqyyz9D6KHKRE0oo2Aw/
    fy+F5ACe+PCpi0A0MptQgk5ePEDjXO5+TdYsOXdgSlXrHRoJ6bnpSDDB4SdpyJ4/
    jNEGS3lOxNSyP70JVxZyVkZ1SzDH3UBzDruDP5EVAoGAGl5IhadThpODVbV+0s51
    V8ZRHgzYAHZv4CdPCqugRP+vMIzoQEaiMMODY8JUzH2wi/qJWwHB7nqeCBS63I1O
    HJjRE8D9qSbhiuR2L3E3mgK6TWGPKQQqAz3NUwml0gQSZAZqhLj9lDQtBJlWkG7A
    kNPV6fWKE6QCp2JR/kAJU6E=
    -----END PRIVATE KEY-----";


    const generateRandomString = function() {
    for (var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 6,
    r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 8,
    e = "abcdefghijklmnopqrstuvwxyz0123456789",
    n = Math.floor(Math.random() * (r - t + 1)) + t,
    o = "", a = 0; a < n; a++) {
    var d = Math.floor(Math.random() * e.length);
    o += e[d]
    }
    return "".concat(o)
    };


    function generateSignatureHeaders() {
    // 生成当前时间戳(秒级)
    const timestamp = Math.floor(Date.now() / 1000).toString();
    // 生成随机字符串(使用默认长度范围 6-8 )
    const nOnce= generateRandomString();
    // 待签名的字符串
    const signatureStr = `${timestamp}\n${nonce}\nade2223c47623d82ecbc413fa5cc6dc1\n`;

    // 初始化 RSA 密钥
    const rsaKey = jsrsasign.KEYUTIL.getKey(RSA_SIGN_KEY);

    // 初始化签名器
    const signature = new jsrsasign.KJUR.crypto.Signature({
    alg: "SHA256withRSA"
    });

    // 进行签名
    signature.init(rsaKey);
    signature.updateString(signatureStr);
    const signedHex = signature.sign();
    const signedBase64 = jsrsasign.hextob64(signedHex);

    return {
    "X-Ca-Timestamp": timestamp,
    "X-Ca-Nonce": nonce,
    "X-Ca-Signature": signedBase64
    };
    }
    v1
        7
    v1  
       87 天前   1
    单就这个帖子,都能当作呈堂证供了……你们交流好歹用截图,图床至少随时能删
    root71370
        8
    root71370  
       87 天前 via Android
    666 学到了
    python35
        9
    python35  
       87 天前
    六百六十六 还是 V 友神人多 只要不是实名上网问题不大
    Monad
        10
    Monad  
       87 天前
    @microBlock #6 大佬有没有可能授人以渔
    microBlock
        11
    microBlock  
       86 天前   1
    @Monad 面向监狱编程
    fire2y
        12
    fire2y  
    OP
       86 天前
    @microBlock 大佬太了 我是真没找到函数是哪里变出来的
    microBlock
        13
    microBlock  
       86 天前
    @fire2y 我用 ai 写的
    microBlock
        14
    microBlock  
       86 天前
    @fire2y 你先试试能不能正常用 我没测试
    fire2y
        15
    fire2y  
    OP
       86 天前
    @microBlock 成了 一把过 逼
    JimLee0921
        16
    JimLee0921  
       86 天前
    为什么好像之前看到过这个羽毛球馆预约帖子???
    shen13176101
        17
    shen13176101  
       86 天前
    @JimLee0921 #16 之前我发过一个羽毛球的帖子,每次定场地 需要发送验证码 这样 一个手机只能抢一个场地,问有没有好办法处理,接口没有加密字段,但是服务器会判断是否是脚本,会封号。最后 不搞了。后来听说八点抢场地,七点五十八就有人可以提前发送验证码,当时我觉得很奇怪,发送验证码的接口明明有时间校验。搞不懂。
    iwfd965
        18
    iwfd965  
       86 天前 via iPhone
    收藏学习
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2462 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 02:38 PVG 10:38 LAX 18:38 JFK 21:38
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86