一、技术背景与场景分析
1.1 报销发票系统的技术特征
现代报销系统普遍采用前后端分离架构,前端通过Vue/React构建动态界面,后端采用Spring Cloud微服务架构。数据交互依赖加密的JSON格式请求,关键字段如发票号码、金额、开票日期等均经过非对称加密处理。
典型请求示例:
// 加密请求体示例const encryptedData = {cipherText: "a1b2c3...", // AES加密后的数据iv: "d4e5f6...", // 初始化向量keyId: "pubKey_2023" // 公钥标识}
1.2 JS逆向的必要性
传统爬虫直接请求API接口会触发WAF防护,返回403错误。通过逆向分析前端JS代码,可破解:
- 动态生成的加密参数(如token、sign)
- 请求时间戳的校验逻辑
- 参数排序规则(如按字段名ASCII码排序)
二、核心逆向技术实现
2.1 动态参数解密流程
2.1.1 加密函数定位
使用Chrome DevTools的Source面板,通过XHR断点定位加密函数。典型特征:
- 包含CryptoJS、WebCrypto等加密库调用
- 存在
encrypt、sign等关键字 - 输入为明文数据,输出为Base64字符串
// 示例加密函数(混淆后)function _0x1a2b3c(data) {const _0x4d5e = CryptoJS.AES.encrypt(JSON.stringify(data),_0x6f7g['key'],{ iv: _0x6f7g['iv'] }).toString();return _0x4d5e;}
2.1.2 密钥提取技术
密钥获取的三种途径:
- 硬编码密钥:直接搜索
new CryptoJS.enc.Utf8.parse('...') - 动态生成密钥:跟踪
window._config等全局变量 - 非对称加密:通过RSA算法解密服务端返回的公钥
// RSA公钥提取示例const publicKey = `-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...`;
2.2 请求头构造技术
2.2.1 核心Header字段
| 字段名 | 作用 | 逆向方法 |
|---|---|---|
| X-Token | 身份验证 | 跟踪localStorage.getItem |
| X-Sign | 请求签名 | 定位sign生成函数 |
| X-Timestamp | 时间戳校验 | 模拟new Date().getTime() |
2.2.2 签名算法破解
常见签名算法实现模式:
// MD5签名示例function generateSign(params) {const sortedParams = Object.keys(params).sort().map(key =>`${key}=${params[key]}`).join('&');return CryptoJS.MD5(sortedParams + '_salt').toString();}
三、反爬策略应对方案
3.1 常见防护机制
- 行为检测:鼠标轨迹、点击间隔等
- 设备指纹:Canvas指纹、WebGL指纹
- 频率限制:IP级/账号级限流
3.2 破解技术方案
3.2.1 动态代理池
// 代理切换逻辑示例const proxies = [{ host: '1.1.1.1', port: 8080 },{ host: '2.2.2.2', port: 8080 }];function getProxy() {return proxies[Math.floor(Math.random() * proxies.length)];}
3.2.2 请求头随机化
// 随机User-Agent生成const userAgents = ['Mozilla/5.0 (Windows NT 10.0; Win64; x64)...','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...'];function randomUA() {return userAgents[Math.floor(Math.random() * userAgents.length)];}
四、法律风险与合规建议
4.1 法律边界分析
根据《网络安全法》第二十七条:
- 禁止非法获取计算机信息系统数据
- 禁止提供侵入、非法控制计算机信息系统的程序
4.2 合规数据采集方案
- 官方API接入:优先使用系统开放的API接口
- 用户授权采集:通过OAuth2.0获取用户授权
- 数据脱敏处理:对敏感字段进行哈希处理
五、完整实现示例
5.1 环境准备
# Node.js环境依赖npm install crypto-js jsdom axios
5.2 核心代码实现
const CryptoJS = require('crypto-js');const axios = require('axios');// 密钥配置(需逆向获取)const config = {key: CryptoJS.enc.Utf8.parse('1234567890abcdef'),iv: CryptoJS.enc.Utf8.parse('abcdef1234567890')};// 加密函数function encryptData(data) {return CryptoJS.AES.encrypt(JSON.stringify(data),config.key,{ iv: config.iv }).toString();}// 请求构造async function fetchInvoiceData(invoiceNo) {const encrypted = encryptData({invoiceNo: invoiceNo,timestamp: Date.now()});const response = await axios.post('https://api.example.com/invoice', {encryptedData: encrypted}, {headers: {'X-Token': 'user_token_123','X-Sign': generateSign({ invoiceNo })}});return response.data;}// 签名生成(示例)function generateSign(params) {const str = Object.keys(params).sort().map(k =>`${k}=${params[k]}`).join('&');return CryptoJS.MD5(str + '_secret').toString();}
六、技术演进趋势
- WebAssembly防护:将核心加密逻辑编译为WASM
- TLS指纹识别:通过JS检测客户端TLS配置
- AI风控系统:基于用户行为的实时风险评估
建议持续关注:
- Chrome DevTools的新调试功能
- 加密算法的硬件加速实现
- 反爬技术的机器学习应用
本文提供的技术方案需严格遵守法律法规,建议在获得明确授权的前提下进行技术验证。实际开发中应建立完善的错误处理机制和日志系统,确保数据采集的稳定性和可追溯性。