最近机场云商开门了,手动挡怎么也下不了车,那就直接上柯基

抓包发现请求头有sign、nonceStr参数且每次请求都不一样

POST /api/consumer/order/addOrder HTTP/1.1

Host: www.gza-e.com

Connection: keep-alive

Content-Length: 122

sign: 51538ca78aa0360efc7234c12f157dd0

timestamp: 1667361180

accessToken: ODg5NjU0NzU4MTc5MDc4MTQ0OjE6ZWQ2NDNmYjc1MzgxNDk4Y2IxNTI0M2QzYWRiZDQ2NjA=

content-type: application/json

nonceStr: d7f0aa20caf546d08c3f0289486a62dc

Accept-Encoding: gzip,compress,br,deflate

User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.29(0x18001d34) NetType/4G Language/en

Referer: https://servicewechat.com/wx88c590140de89f92/203/page-frame.html

{"orgId":"817425775685795840","proProType1":3,"orderDetailList":[{"ostId":"","proId":"1003627106498117633","quantity":1}]}

话不多说直接反编译小程序在源码中搜索某sign发现一个函数

 跟踪s()函数发现签名算法就在其中

function s(o, n, s, r, i) {

for (var d = "", c = 0, u = Object.keys(o).sort(); c < u.length; c++) {

var l = u[c], f = o[l];

if ("object" === e(f) && null !== f) {

var g = JSON.stringify(o[l]);

d += l + "=" + (g = g.split("").sort().join("")) + "&";

} else 0 === f || f ? d += l + "=" + o[l] + "&" : (o[l] = "", d += l + "=&");

}

return d += "url=" + n + "&", d += s ? "accessToken=" + s + "&" : "", d += "timestamp=" + r + "&",

d += "nonceStr=" + i + "&", d += "key=" + t.default.PLAM_KEY, a.md5Encrypt(d);

}

 进过一系列分析发现签名函数的几个参数分别为post所提交的json数据,请求的url,accessToken,timestamp和nonceStr这几个参数,至于PLAM_KEY则为一个固定值,接下来就是找到nonceStr的算法了

跟踪源码发现:

nonceStr这个参数是随机的,且"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx"中的“4”作为验证,timestamp则为时间戳,接下来就简单了,直接改写签名算法

java版

package com.hotel.hotelmaster.test;

import com.alibaba.fastjson.JSONObject;

import org.apache.commons.codec.digest.DigestUtils;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import java.util.UUID;

/**

* @author yangchen

*/

public class SignUtils {

public static final String HOST = "https://www.gza-e.com/api";

public static final String PLAM_KEY = "ca235e27dcf94107889b9ad00ceebd48";

/**

* 获取nonceStr

*

* @return

*/

public static String getNonceStr() {

return UUID.randomUUID().toString().replace("-", "");

}

/**

* 获取时间戳

*

* @return

*/

public static Long getTimestamp() {

return System.currentTimeMillis() / 1000;

}

/**

* 判断是否为json对象

*

* @param str

*/

public static boolean getJsonType(String str) {

boolean result = false;

if (str != null) {

str = str.trim();

if (str.startsWith("{") && str.endsWith("}")) {

result = true;

} else if (str.startsWith("[") && str.endsWith("]")) {

result = true;

}

}

return result;

}

/**

* 签名接口

*

* @param postData

* @param url

* @param accessToken

* @param timestamp

* @param nonceStr

*/

public static String signature(JSONObject postData, String url, String accessToken, long timestamp, String nonceStr) {

List keyList = new ArrayList<>();

String d = "";

for (String key : postData.keySet()) {

keyList.add(key);

}

Collections.sort(keyList);

for (int i = 0; i < keyList.size(); i++) {

String key = keyList.get(i);

String value = postData.get(key).toString();

if (getJsonType(value) && value != null) {

List valueList = new ArrayList<>();

for (int j = 0; j < value.length(); j++) {

valueList.add(String.valueOf(value.charAt(j)));

}

Collections.sort(valueList);

d += key + "=";

for (int k = 0; k < valueList.size(); k++) {

d += valueList.get(k);

}

d += "&";

} else {

d += key + "=" + value + "&";

}

}

d += "url=" + url.replace(HOST, "") + "&";

d += "accessToken=" + accessToken + "&";

d += "timestamp=" + timestamp + "&";

d += "nonceStr=" + nonceStr + "&";

d += "key=" + PLAM_KEY;

return DigestUtils.md5Hex(d);

}

public static void main(String[] args) {

String url="https://www.gza-e.com/api/consumer/order/addOrder";

String accessToken = "ODg5NjU0NzU4MTc5MDc4MTQ0OjE6ZWQ2NDNmYjc1MzgxNDk4Y2IxNTI0M2QzYWRiZDQ2NjA=";

String nonceStr= "d7f0aa20caf546d08c3f0289486a62dc";

JSONObject postData=JSONObject.parseObject("{\"orgId\":\"817425775685795840\",\"proProType1\":3,\"orderDetailList\":[{\"ostId\":\"\",\"proId\":\"1003627106498117633\",\"quantity\":1}]}");

long timestamp= 1667361180;

String sign=signature(postData,url,accessToken,timestamp,nonceStr);

System.out.println(sign);

}

python版

def signature(postData, url, accessToken, timestamp, nonceStr):

PLAM_KEY = "ca235e27dcf94107889b9ad00ceebd48"

host = "https://www.gza-e.com/api"

url = url.replace(host, "")

keys = sorted(postData.keys())

d = ""

for key in keys:

if isinstance(postData[key], list) or isinstance(postData[key], dict) or postData[key] is None:

g = str(json.dumps(postData[key])).replace(" ", "")

ls = []

for i in range(len(g)):

ls.append(g[i])

ls.sort()

d += key + "="

for s in ls:

d += s

d += "&"

else:

d += key + "=" + str(postData[key]) + "&"

d += "url=" + url + "&"

d += "accessToken=" + accessToken + "&"

d += "timestamp=" + str(timestamp) + "&"

d += "nonceStr=" + nonceStr + "&"

d += "key=" + PLAM_KEY

return hashlib.md5(d.encode("utf8")).hexdigest()

用刚刚抓包的结果验证一下签名结果相同

再重新发起一个新的请求看看是否能够请求成功

大功告成,完美!

仅供学习参考!!!

 

 

 

 

 

 

 

 

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。