前阵子做公开资讯数据采集项目,碰上个地方新闻门户。列表页能正常访问,可一旦请求正文内容接口,就必须带一个叫x-sign-token的请求头,直接复制浏览器里的token,五六分钟就失效,纯HTTP客户端构造请求直接返回403。
一开始以为就是个简单的时间戳MD5签名,抓了两次包就想自己拼,结果连着试了七八次全是403,连个错误提示都没有。后来硬着头皮扒混淆的前端JS,前前后后折腾了两天,才把整套逻辑扒明白:根本不是对称签名,是前端用RSA公钥加密明文,后端用私钥解密校验,公钥和加密逻辑全藏在混淆后的JS里,还做了控制流平坦化,单步调试绕得人头晕。
今天就把完整的逆向过程、加密还原、踩坑细节全部分享出来,思路通用,绝大多数带RSA签名的站点都能按这个路子拆。
一、先定位:Token到底是前端生成还是后端下发?
动手逆向之前,先搞清楚token的来源,能少走很多弯路。瞎搜关键词、乱翻JS文件,只会浪费时间。
1.1 抓包初步排查
第一步先开浏览器DevTools的Network面板,刷新页面,抓正文接口的请求,重点看三个点:
- 看请求头里的
x-sign-token,每次刷新页面值都不一样,说明是动态生成的。 - 翻所有的请求记录,没有任何一个接口是专门返回token的,连个配置接口都没有。
- 禁用浏览器缓存,刷新后token还是立刻生成,不需要等后端返回。
基本就能判定:token是前端JS在本地生成的,不是后端下发的。