加密参数逆向工程(请求签名、Token生成机制破解)
调试器停在了/api/v1/books的请求前,Network面板里那个长达256位的X-Signature字段格外刺眼。昨天还能正常响应的接口,今早突然全部返回403。刷新页面,发现每个请求的签名值都在变化——显然,我们撞上了服务端的动态签名验证层。这不再是简单的User-Agent轮换能解决的问题,真正的加密对抗开始了。
一、请求签名的本质
现代反爬体系中的签名机制,本质上是服务端对客户端“身份合法性”的二次校验。它通常不依赖Cookie或Session,而是通过算法将请求参数、时间戳、密钥等元素混合运算,生成一段随请求变化的字符串。服务器用同样算法验算,不一致则拒绝。ZLibrary的签名出现在三个关键位置:搜索接口、详情页加载、文件下载触发点。
在Chrome开发者工具中,我们锁定了一个典型请求:搜索关键词“python”时,POST请求体包含keywords、page、timestamp和signature四个字段。前两个是业务参数,后两个明显是验证参数。尝试修改timestamp的毫秒值,签名立即失效;修改keywords则提示“签名错误”。这说明签名与这些参数强关联。
二、逆向入口定位技巧
前端的加密逻辑通常出现在两个位置:一是页面内联的JavaScript代码块,二是独立的Webpack打包模块。在ZLibrary的页面源码里搜索“signature”或“sign”,很快在<script>标签里发现一个名为_generateSignature的函数。但它的内容被压缩成了一行,变量名都是a、b、c这类短名。
这时候别急着格式化代码——先看堆栈。在Network面板找到那个带签名的请求,右键选择“Copy -> Copy as cURL”,然后在Console里执行它,会触发浏览器对请求的完整重放。接着在Sources面板的“Event Listener Breakpoints”中勾选“XHR/fetch Breakpoints”,添加一个URL包含/api/v1/的断点。重新触发请求,执行流会在发送前暂停。
顺着调用栈向下看,第三个栈帧指向一个名为security.js的文件。点击进入,格式化代码,核心逻辑暴露出来:
function generateSignature(params, secretKey) {
// 参数按字典序排序,这里踩过坑:服务端对空值处理不一致
let sortedKeys = Object.keys(params).sort();
let baseString = '';
sortedKeys.forEach(key => {
// 注意:布尔值会被转成字符串'true'/'false'
let value = params

&spm=1001.2101.3001.5002&articleId=159610121&d=1&t=3&u=754230a3ac2e4163adec9db0a51a4aca)
1128

被折叠的 条评论
为什么被折叠?



