1. 引入包的问题
2. 原因
.pycrypto、pycrytodome和crypto是一个东西,crypto在python上面的名字是pycrypto,它是一个第三方库,但是已经停止更新
3. 解决方法
--直接安装:pip install pycryptodome
3.但是,在使用的时候导入模块是有问题的,这个时候只要修改一个文件夹的名称就可以完美解决这个问题,
Python\Python36\Lib\site-packages,找到这个路径,下面有一个文件夹叫做crypto,将小写c改成大写C就ok了
4. 核心加密算法
def get_sign(data):
logging.warning(f"-------------生成sign的传入的请求体数据:{data}")
PRIVATE_KEY_2 = '''MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMNvMFAJ5Ut6Yyba6xndMOl5yOTEU8T/oCzFYAbsnOxcpTHij7xSr8ls1YMv8AQf2igiIK8wJj3y52M2AiMFaDcnkhJ0cUDRRVMMYmuZSWiOpUcH+ET5q9jJH56ZT90trjqab987gvk5fHnBa0cM4HHYmo7xa+Qh11CVLdkeKmOhAgMBAAECgYB/SR+yQX+x1RhW6iZNRh7hMYyCUswsdkEgZ7zPRbQ+zWhaQTFUepY7HkNBmis8xHIVyYR4FWgS2O2TVE23+YGRpudEUMS/C/PcolTQWYBlR3Bvqsdw88tdurDWoHg/+GKaHlR5RBj2zVYPf6meXg/mYLt9xXRU0yDgyXxEWGsgAQJBAOqHXfS7Jfi8giLjwgAN1kbfdSh1WqSalnXdELrM3VZFW/+q9AQI0TOrJsCYfbzyIzbwl6a7DCUj5LOQZEG2tUECQQDVU5Fy6w1uXDDP3U/ccuyayu9ixHVWHv8Rdprpe2RPDr9EiF6tqe1y30gTywBZCJkLpEPpNK4zB1Daps08tDZhAkEAocxD0JvwRVrfuOxCIcFqC7kL3Z6gqyCPHr8lVIoTRPpSzt6Eu+fNVAUGliZd0KWID9YJ+ZffeBv8IrlBwWgoQQJBALI71DZTtTETzaSen+7sBkt+amv3AKIn26zXj66r7a8v/xZfadtnMoDblPkUjwHUcSqM4ECkRzdTUXaeDrQ9TYECQD7Fx4ZEphiWIfKSS+W4C9ZYpx6KcRLSehG9tHBNRc4CA/dRZprdRQL7ZpJLm2xhaXFQ0RGyzEyZEDS3Ugm+7fI='''
privateKey = PRIVATE_KEY_2
private_keyBytes = base64.b64decode(privateKey)
priKey = RSA.importKey(private_keyBytes)
signer = PKCS1_v1_5.new(priKey)
hash_obj = MD5.new(data.encode('utf-8'))
signature = base64.b64encode(signer.sign(hash_obj))
import urllib.parse
da = urllib.parse.quote(signature)
return da
5. sign1生成依赖动态参数
5.1. get请求;
device_id + device_type + device_ver + timestamp + token
动态参数:stimestamp token
解决方案:提升级别,全抽离前置处理
def setup_hooks_request(request):
logging.warning(f"---step前置的request信息:{request}")
_timestamp = get_pp_timestamp()
multi_env = {'multi_env': 'wl'}
_device_id = get_device_id()
_device_type = get_device_type()
_device_ver = get_device_ver()
_token = get_token()
data = get_data(_timestamp, _token)
_get_pp_sign = get_sign(data)
pp_device_id = {'pp_device_id': _device_id}
pp_device_type = {'pp_device_type': _device_type}
pp_client_ver = {'pp_client_ver': _device_ver}
pp_token = {'pp_token': _token}
pp_req_sign = {'pp_req_sign': _get_pp_sign}
pp_timestamp = {'pp_timestamp': _timestamp}
header = {'multi_env': multi_env}
header = {'pp_device_id': pp_device_id}
header = {'pp_device_type': pp_device_type}
header = {'pp_client_ver': pp_client_ver}
header = {'pp_token': pp_token}
header = {'pp_req_sign': pp_req_sign}
header = {'pp_timestamp': pp_timestamp}
if 'headers' in request:
if bool(request['headers']) is True:
request['headers'].update(multi_env)
request['headers'].update(pp_device_id)
request['headers'].update(pp_device_type)
request['headers'].update(pp_client_ver)
request['headers'].update(pp_token)
request['headers'].update(pp_req_sign)
request['headers'].update(pp_timestamp)
else:
request['headers'].update(header)
else:
request['headers'] = header
return request
6. sign2依赖body数据
6.1. post请求
6.1.1. request级别提前参数化data
# 参数化body数据
.with_variables(
**{"data": '{"month": "2024-03"}'}
)
# 单独header hook
.with_headers(
**{
"pp_req_sign_2": "${get_pp_sign(data=$data)}",
}
)
6.1.2. 获取request后,函数处理
request参数信息
---step前置的request信息:{'method': 'POST', 'url': '/api/online-agent-product/annualBill/monthSavings', 'params': {}, 'req_json': None, 'data': '{"month": "2024-03"}', 'cookies': {}, 'timeout':
120, 'allow_redirects': True, 'verify': False, 'headers': {'accept-encoding': 'gzip', 'content-length': '19', 'content-type': 'application/json; charset=UTF-8', 'pp_channel': 'googleplay', 'pp_req_sign_2': 'AU3DMz02Hda0Y8m2Dv
kOz2%2BOuHD1t/pR3yIPmudCer8BOGYOBp1pnzfCh6ttOe7BfYKsrE%2Bhluts9tkcCbM7/HFhOH8RQaUSfl6LkM9mqpaNb9FmBZTBUMHXk9dcqHAlENtdVUUvbUWLQEr1XNZK/OW0AXoqhm51gncxXVXL7hc%3D', 'user-agent': 'PalmPay/5.3.0&603020703 (Android 13)', 'HRUN-Request-ID': 'HRUN-a5eec8e9-de59-487c-8979-0a8fb0c19436-684135'}}
关键代码
.with_data('{"month": "2024-03"}')
# 请求体参数
body_data = request.get('data') if request.get('data') else request.get('req_json')
if body_data:
sign2 = get_sign(body_data)
else:
sign2 = _get_pp_sign