ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

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

招聘网站数据接口逆向分析:SM2/SM3/SM4加密实战 1. 招聘网站数据接口逆向分析实战最近在研究某招聘网站的数据采集时遇到了三个关键加密参数businessData、e-sign和e-content-path。这三个参数都采用了不同的加密方式且都会随请求变化。经过一番折腾终于成功逆向出完整的加密逻辑。下面就把我的分析过程和解决方案分享给大家。1.1 目标网站加密特点分析这个招聘网站采用了比较完善的反爬机制主要体现在以下几个方面核心数据接口使用了三个动态加密参数businessData参数采用SM4加密e-sign参数采用SM3哈希e-content-path参数涉及SM2非对称加密前端代码使用了Webpack打包增加了分析难度提示在实际逆向过程中建议使用Chrome开发者工具的条件断点功能可以大幅提高调试效率。2. 接口分析与参数定位2.1 数据接口识别首先通过浏览器开发者工具观察页面加载过程打开网站首页使用无痕模式避免缓存干扰点击任意职位分类如IT/互联网 测试工程师在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关键词可以定位到生成该参数的代码位置。通过分析发现参数值是通过一个名为_的函数生成函数内部有明显的SM4加密特征加密模式为CBC使用PKCS7填充需要key和iv两个关键参数加密核心代码如下function _(t) { return sm t.type ? sm4.encrypt( t.word, t.key, { mode: cbc, iv: t.iv, output: hex } ) : /* 其他情况 */; }3.2 关键参数获取要复现加密过程需要获取以下三个要素明文(word)包含搜索条件的JSON字符串如{target:SEARCH_RESULT_PAGE,query:测试工程师}密钥(key)通过E函数生成涉及多个嵌套函数调用初始向量(iv)生成逻辑与key类似3.2.1 密钥生成逻辑密钥生成主要经过以下步骤调用E函数传入固定参数t内部调用m函数生成随机数使用w函数处理随机数最终输出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参数的生成相对简单通过搜索可以发现由b函数生成实际是SM3哈希算法输入为固定字符串business加上businessData值再加上data输出为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加密分析这个参数是最复杂的涉及以下技术点使用SM2非对称加密需要处理Webpack模块加载涉及多个临时参数的生成需要特定的公钥进行加密加密过程主要步骤生成两个32字节随机数x和C使用SM2加密特定数据拼接加密结果生成最终值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, page1): 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, headersheaders, jsonpayload ) return response.json()6.2 注意事项在实际使用中需要注意请求频率控制即使破解了加密也应遵守robots.txt和合理爬取间隔参数时效性加密参数可能有时间敏感性不宜长时间缓存错误处理网站可能调整加密逻辑需要完善的错误监控法律合规仅爬取公开数据避免个人信息和商业机密7. 常见问题与解决方案7.1 加密结果不一致可能原因及解决方法密钥生成差异检查随机数生成逻辑是否完全一致编码问题确保所有中间步骤使用相同的编码方式填充模式确认使用PKCS7填充加密模式必须是CBC模式7.2 Webpack模块加载问题处理建议提取完整的Webpack加载器代码在本地模拟模块加载环境使用global.loader替代原生的__webpack_require__7.3 请求被拒绝排查步骤验证三个加密参数是否都正确生成检查请求头是否完整特别是Content-Type确认User-Agent是常见的浏览器标识尝试添加Referer等常见反爬头8. 技术要点总结通过这次逆向分析我们可以总结出几个关键经验条件断点是调试动态加密代码的利器Webpack打包的代码可以通过模块ID定位具体函数国密算法SM2/SM3/SM4在Web加密中应用越来越广泛复合加密对称非对称哈希正在成为反爬标配对于想要学习Web逆向的朋友我的建议是从简单的网站开始逐步提升难度熟练掌握开发者工具的各种调试功能建立自己的代码片段库积累常见加密算法实现关注WebAssembly等新技术的应用最后提醒大家技术研究要遵守法律法规尊重网站的数据权益将爬虫技术用在正当的用途上。
返回列表