news 2026/8/23 11:33:41

招聘网站数据接口逆向分析:SM2/SM3/SM4加密实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
招聘网站数据接口逆向分析:SM2/SM3/SM4加密实战

1. 招聘网站数据接口逆向分析实战

最近在研究某招聘网站的数据采集时,遇到了三个关键加密参数:businessData、e-sign和e-content-path。这三个参数都采用了不同的加密方式,且都会随请求变化。经过一番折腾,终于成功逆向出完整的加密逻辑。下面就把我的分析过程和解决方案分享给大家。

1.1 目标网站加密特点分析

这个招聘网站采用了比较完善的反爬机制,主要体现在以下几个方面:

  1. 核心数据接口使用了三个动态加密参数
  2. businessData参数采用SM4加密
  3. e-sign参数采用SM3哈希
  4. e-content-path参数涉及SM2非对称加密
  5. 前端代码使用了Webpack打包,增加了分析难度

提示:在实际逆向过程中,建议使用Chrome开发者工具的"条件断点"功能,可以大幅提高调试效率。

2. 接口分析与参数定位

2.1 数据接口识别

首先通过浏览器开发者工具观察页面加载过程:

  1. 打开网站首页,使用无痕模式避免缓存干扰
  2. 点击任意职位分类(如"IT/互联网 > 测试工程师")
  3. 在Network面板筛选XHR请求

经过多次测试发现,真实的数据请求接口会携带三个关键参数:

POST /api/job/search HTTP/1.1 Host: xxx.com Content-Type: application/json { "businessData": "a1b2c3...", "e-sign": "d4e5f6...", "e-content-path": "g7h8i9..." }

这三个参数每次请求都会变化,且缺一不可。服务器会对这些参数进行严格校验,直接复制前一次的参数值会导致请求失败。

2.2 加密参数初步分析

通过对比多次请求,可以总结出三个参数的特点:

参数名称长度变化规律疑似加密方式
businessData变长随请求内容变化SM4加密
e-sign64字符与businessData相关SM3哈希
e-content-path88字符独立变化SM2加密

3. businessData参数逆向

3.1 SM4加密识别

在开发者工具中搜索"businessData"关键词,可以定位到生成该参数的代码位置。通过分析发现:

  1. 参数值是通过一个名为"_"的函数生成
  2. 函数内部有明显的SM4加密特征
  3. 加密模式为CBC,使用PKCS7填充
  4. 需要key和iv两个关键参数

加密核心代码如下:

function _(t) { return "sm" === t.type ? sm4.encrypt( t.word, t.key, { mode: 'cbc', iv: t.iv, output: 'hex' } ) : /* 其他情况 */; }

3.2 关键参数获取

要复现加密过程,需要获取以下三个要素:

  1. 明文(word):包含搜索条件的JSON字符串,如:
    {"target":"SEARCH_RESULT_PAGE","query":"测试工程师"}
  2. 密钥(key):通过E函数生成,涉及多个嵌套函数调用
  3. 初始向量(iv):生成逻辑与key类似
3.2.1 密钥生成逻辑

密钥生成主要经过以下步骤:

  1. 调用E函数,传入固定参数t
  2. 内部调用m函数生成随机数
  3. 使用w函数处理随机数
  4. 最终输出32字节的hex字符串

补全后的Node.js实现:

const crypto = require('crypto'); function getRandomValues(typedArray) { if (!(typedArray instanceof Uint8Array)) { throw new TypeError('参数必须是Uint8Array类型'); } const randomBuffer = crypto.randomBytes(typedArray.length); typedArray.set(randomBuffer); return typedArray; } function m(length) { const t = new Uint8Array(length); return getRandomValues(t); } function w(input) { // 实际网站中的特定处理逻辑 return Buffer.from(input).toString('hex'); } function E() { const t = m(16); const randomBytes = m(32); return w(randomBytes); }
3.2.2 完整SM4加密实现

结合上述分析,完整的businessData生成代码如下:

const { sm4 } = require('sm-crypto'); function generateBusinessData(searchParams) { const plaintext = JSON.stringify({ target: "SEARCH_RESULT_PAGE", ...searchParams }); const key = E(); // 使用上述E函数生成 const iv = E(); // 生成逻辑与key相同 return sm4.encrypt(plaintext, key, { mode: 'cbc', iv: iv, output: 'hex' }); }

4. e-sign参数逆向

4.1 SM3哈希识别

e-sign参数的生成相对简单,通过搜索可以发现:

  1. 由b函数生成,实际是SM3哈希算法
  2. 输入为固定字符串"business"加上businessData值再加上"data"
  3. 输出为64字符的hex字符串

关键代码位置:

var b = global.loader("gGBh").sm3; var o = b("business" + n + "data"); // n为businessData值

4.2 Node.js实现

使用sm-crypto库的SM3实现:

const { sm3 } = require('sm-crypto'); function generateESign(businessData) { return sm3(`business${businessData}data`); }

5. e-content-path参数逆向

5.1 SM2加密分析

这个参数是最复杂的,涉及以下技术点:

  1. 使用SM2非对称加密
  2. 需要处理Webpack模块加载
  3. 涉及多个临时参数的生成
  4. 需要特定的公钥进行加密

加密过程主要步骤:

  1. 生成两个32字节随机数x和C
  2. 使用SM2加密特定数据
  3. 拼接加密结果生成最终值

5.2 关键代码实现

补全后的Node.js代码:

const { sm2 } = require('sm-crypto'); // 网站使用的固定公钥 const PUBLIC_KEY = '043f4a9673db98fd52a87e087da75ca8d4978748188e29373acc131887d7b78ee89b07364f644352e4cb4029d8330509368b27b10638345c8afd41149626d917aa'; function generateEContentPath() { const x = m(32); // 随机数1 const C = m(32); // 随机数2 const dataToEncrypt = Buffer.concat([ Buffer.from(x), Buffer.from(C) ]).toString('hex'); // SM2加密 const encrypted = sm2.doEncrypt( dataToEncrypt, PUBLIC_KEY, { inputEncoding: 'hex', outputEncoding: 'base64' } ); return Buffer.from(encrypted, 'base64').toString('hex'); }

6. 完整请求流程实现

6.1 Python实现示例

将上述分析结果整合为Python爬虫代码:

import requests from sm_crypto import sm2, sm3, sm4 def generate_business_data(search_params): # 实现SM4加密逻辑 pass def generate_e_sign(business_data): # 实现SM3哈希逻辑 pass def generate_e_content_path(): # 实现SM2加密逻辑 pass def fetch_job_data(keyword, page=1): business_data = generate_business_data({ "query": keyword, "page": page }) e_sign = generate_e_sign(business_data) e_content_path = generate_e_content_path() headers = { "User-Agent": "Mozilla/5.0", "Content-Type": "application/json" } payload = { "businessData": business_data, "e-sign": e_sign, "e-content-path": e_content_path } response = requests.post( "https://xxx.com/api/job/search", headers=headers, json=payload ) return response.json()

6.2 注意事项

在实际使用中需要注意:

  1. 请求频率控制:即使破解了加密,也应遵守robots.txt和合理爬取间隔
  2. 参数时效性:加密参数可能有时间敏感性,不宜长时间缓存
  3. 错误处理:网站可能调整加密逻辑,需要完善的错误监控
  4. 法律合规:仅爬取公开数据,避免个人信息和商业机密

7. 常见问题与解决方案

7.1 加密结果不一致

可能原因及解决方法:

  1. 密钥生成差异:检查随机数生成逻辑是否完全一致
  2. 编码问题:确保所有中间步骤使用相同的编码方式
  3. 填充模式:确认使用PKCS7填充
  4. 加密模式:必须是CBC模式

7.2 Webpack模块加载问题

处理建议:

  1. 提取完整的Webpack加载器代码
  2. 在本地模拟模块加载环境
  3. 使用global.loader替代原生的__webpack_require__

7.3 请求被拒绝

排查步骤:

  1. 验证三个加密参数是否都正确生成
  2. 检查请求头是否完整(特别是Content-Type)
  3. 确认User-Agent是常见的浏览器标识
  4. 尝试添加Referer等常见反爬头

8. 技术要点总结

通过这次逆向分析,我们可以总结出几个关键经验:

  1. 条件断点是调试动态加密代码的利器
  2. Webpack打包的代码可以通过模块ID定位具体函数
  3. 国密算法(SM2/SM3/SM4)在Web加密中应用越来越广泛
  4. 复合加密(对称+非对称+哈希)正在成为反爬标配

对于想要学习Web逆向的朋友,我的建议是:

  1. 从简单的网站开始,逐步提升难度
  2. 熟练掌握开发者工具的各种调试功能
  3. 建立自己的代码片段库,积累常见加密算法实现
  4. 关注WebAssembly等新技术的应用

最后提醒大家,技术研究要遵守法律法规,尊重网站的数据权益,将爬虫技术用在正当的用途上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/23 11:33:39

3步刷好ESP8266:Tasmotizer完整指南

3步刷好ESP8266:Tasmotizer完整指南 【免费下载链接】tasmotizer ESP... The time has come to... Tasmotize! 项目地址: https://gitcode.com/gh_mirrors/ta/tasmotizer Tasmotizer是一款面向ESP8266设备的图形化刷机工具。它把备份原固件、写入Tasmota固件…

作者头像 李华
网站建设 2026/8/23 11:32:34

C++模板:从泛型编程到编译期计算的实战指南

1. 从“重复造轮子”到“一劳永逸”:为什么我们需要C模板? 如果你写过一段时间的C,尤其是写过一些需要处理多种数据类型的工具函数或数据结构,你大概率经历过这种痛苦:为了给 int 、 double 、 string 各写一个功…

作者头像 李华
网站建设 2026/8/23 11:32:30

AI意识工程观察:从现象到评估的开发者实践指南

1. 先搞清楚“AI意识”讨论的到底是什么问题当我们在讨论“AI能否拥有意识”时,很多人会立刻陷入科幻电影式的想象,或者被各种哲学思辨绕晕。作为一个在技术一线折腾了十多年的从业者,我更建议先把这个问题拆解成几个可以实际观察和判断的层面…

作者头像 李华
网站建设 2026/8/23 11:30:11

如何用Pkg.jl的[compat]锁定依赖版本区间:兼容性配置完整指南

如何用Pkg.jl的[compat]锁定依赖版本区间:兼容性配置完整指南 【免费下载链接】Pkg.jl Pkg - Package manager for the Julia programming language 项目地址: https://gitcode.com/gh_mirrors/pk/Pkg.jl Pkg.jl 是 Julia 语言的官方包管理器,而其…

作者头像 李华