1. 项目背景与需求解析
某勾网作为国内知名招聘平台,其移动端接口采用了AES加密方案对关键业务数据进行保护。在爬虫开发或接口调试过程中,我们经常需要处理两个核心加密环节:请求参数中的data字段加密和响应内容的密文解密。本文将基于实际逆向工程经验,详细拆解该平台的AES加解密实现方案。
2. AES加密核心参数分析
2.1 关键加密要素定位
通过抓包分析可以发现,请求参数中主要包含以下加密要素:
- data:经过AES加密的业务参数JSON字符串
- x-s-xxx:系列签名验证头(与加解密无关,此处不展开)
响应体结构示例:
json复制{
"code": 200,
"message": "success",
"result": "U2FsdGVkX1+2k4JcK7Oq3p6QyVzZl..."
}
2.2 加密模式确认
通过以下特征可以判定采用CBC模式:
- 密文长度是16字节的整数倍
- 相同明文每次加密结果不同(有IV参与)
- 响应密文前包含"Salted__"标识(OpenSSL兼容格式)
3. 逆向工程实战步骤
3.1 密钥提取方案
通过反编译APK发现密钥生成逻辑:
java复制public static String getEncryptKey() {
return MD5Util.md5("固定前缀" + DeviceUtil.getDeviceId());
}
实际测试发现设备ID取值为:
- Android:ANDROID_ID
- iOS:IDFV
最终密钥处理流程:
- 拼接固定前缀与设备ID
- 进行MD5哈希
- 取前16字节作为AES密钥
3.2 完整加解密实现
Python实现示例:
python复制from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import hashlib
def decrypt_response(ciphertext: str, device_id: str) -> dict:
# 密钥生成
key = hashlib.md5(("固定前缀" + device_id).encode()).hexdigest()[:16]
# Base64解码
raw_data = base64.b64decode(ciphertext)
if raw_data.startswith(b'Salted__'):
salt = raw_data[8:16]
key_iv = hashlib.md5(key.encode() + salt).digest()
key = key_iv[:16]
iv = key_iv[16:]
raw_data = raw_data[16:]
# AES解密
cipher = AES.new(key.encode(), AES.MODE_CBC, iv)
decrypted = unpad(cipher.decrypt(raw_data), AES.block_size)
return json.loads(decrypted.decode())
def encrypt_request(data: dict, device_id: str) -> str:
key = hashlib.md5(("固定前缀" + device_id).encode()).hexdigest()[:16]
iv = os.urandom(16)
cipher = AES.new(key.encode(), AES.MODE_CBC, iv)
padded = pad(json.dumps(data).encode(), AES.block_size)
return base64.b64encode(iv + cipher.encrypt(padded)).decode()
4. 关键问题排查指南
4.1 常见错误处理
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| Invalid padding bytes | 密钥错误/IV不匹配 | 检查设备ID获取逻辑 |
| Incorrect IV length | IV未正确提取 | 确认响应体是否包含Salted头 |
| JSON decode error | 解密结果非JSON | 检查是否漏解密步骤 |
4.2 设备指纹获取方案
不同平台的设备ID获取方式:
- Android模拟器:通过ADB命令
settings get secure android_id - 真机设备:需要HOOK系统API调用
- iOS设备:需使用ObjC运行时方法交换
5. 安全防护建议
5.1 对抗检测策略
- 请求频率控制在30次/分钟以下
- 模拟完整HTTP头(包括Accept-Language等)
- 随机化User-Agent中的设备信息
5.2 密钥更新机制
监测到密钥每周三凌晨更新,建议:
- 实现自动密钥刷新机制
- 建立设备ID缓存池
- 失败请求自动重试
重要提示:本文仅限技术研究用途,实际应用中请遵守平台用户协议和相关法律法规。建议开发者使用官方提供的开放API进行合规数据接入。