该文章只是用于逆向学习,不得以商用或者是破坏他人利益的目的进行使用。如有侵权请联系作者。
网站链接:
bse64
aHR0cHM6Ly9nZ3p5ZncuZnVqaWFuLmdvdi5jbi9idXNpbmVzcy9saXN0Lw==
分析环节
进入网站 进行翻页请求时我们会发现改请求时ajax请求。
这里,我们可以直接看一下请求参数和返回结果,以及表头携带。
请求参数
请求参数中不存在加密
返回数据
data被加密了
请求头
请求头中存在一个加密参数
此时我们换页,查看改参数是否改变
发生改变,所以我们现在需要做的就是先找到请求头中的 portal-sign的加密位置。
由于数据加密的这个过程中我们并不知道再那个文件中,应为返回数据的话是已经得到加密头了,所以这里我们采用搜索关键字的方法来进行快速定位。这也是为什么我不直接使用xhr断点找加密的原因。
搜索关键词portal-sign
找到关键字,点击进入该js文件
打个断点待会好调试
现在我们已经找到加密的位置了,根据名字可以直接确定,这就是加密的赋值操作,现在开始调试,找到加密函数。
执行一步的时候我们发现他出现到这里了,结合上面的f.getsign(e)可以确定,这个过程是正确的
那么,我们先不扣代码,先走一步看看,执行到这里的时候我们需要看一下这些参数是什么
控制台输出一下r["a"]
这个值先记录一下
输出l(t),我们可以确定的是,l(t)是一个加密的过程
并且我们看参数t是一个对象
中间的ts是一个时间戳,带有请求的一些参数,这个先不管
现在继续进入,进入下图文件中。我们发现这个过程是创建了一个Md5对象并且调用了update方法,所以我们已经可以知道这个结果了,以防万一,我们直接跳过调试观察一下。可以验证个参数就是一个通过md5加密的一个过程,你现在可以采用md5加密验证也可以直接扣下来这段代码,我们使用平台是可以直接知道,这个加密就是MD5加密的一个过程,但是为了锻炼我的扣代码能力,我选择了硬扣。如果你不想查看这个过程的话,可以直接略过。
js扣代码环节
根据我们上边的一些记录我们现在需要做的是,刷新网页,重新打开浏览器,执行一遍这个过程,看看有哪些是固定的。
可以确定r["a"]是没有改变,我们直接搜索这个值看一下有没有
存在,所以现在我们就知道这个过程了,他是将一个请求头t当作参数传递给d在d函数中,通过一个常量和一个加密后的数据进行拼接,然后使用MD5进行加密。
现在开始着手扣第一步代码,得到加密后的n
我喜欢使用html来验证js代码是否完整,所以这里我使用的html讲解
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function s(t, e) {return t.toString().toUpperCase() > e.toString().toUpperCase() ? 1 : t.toString().toUpperCase() == e.toString().toUpperCase() ? 0 : -1
}
function l(t) {for (var e = Object.keys(t).sort(s), n = "", a = 0; a < e.length; a++)if (void 0 !== t[e[a]])if (t[e[a]] && t[e[a]]instanceof Object || t[e[a]]instanceof Array) {var i = JSON.stringify(t[e[a]]);n += e[a] + i} elsen += e[a] + t[e[a]];return n
}
function d(t) {for (var e in t)"" !== t[e] && void 0 !== t[e] || delete t[e];var n = "B3978D054A72A7002063637CCDF6B2E5" + l(t);console.log(n)return u(n).toLocaleLowerCase()
}
t = {"ts": 1702288385369,"type": "12","IS_IMPORT": 1,"pageSize": 3
}
d(t)</script>
</body>
</html>
出现的错误是因为没有找到u(n),我们可以发现已经出现拼接好的n了,那么我们可以确定的是,代码已经成功了一步。
现在开始着手MD5加密环节
进入之后,会返回一个new对象,所以直接将u(n)部分替换
替换的代码
function d(t) {for (var e in t)"" !== t[e] && void 0 !== t[e] || delete t[e];var n = "B3978D054A72A7002063637CCDF6B2E5" + l(t);console.log(n)return new Md5(!0).update(n)[t]()
接下来就i是把整个md5扣下来了
联立前面的代码,我们可以直接放到html中,观察。
这边md5我就不单独放出来了,不然我写着是真的卡
出现错误:找不到这个blocks,那么开始在代码中找这个定义
还顺带找到了buffers,直接拷贝到文件中。
出现错误
直接在浏览器中打印,是一个ture
直接填写,然后在代码中替换。
现在又出现缺少
我们发现是创建函数出了问题,里面少了一个参数t,直接根据提示,发现是一个字符串,在代码中补全。
现在缺少了一个EXTRA
开始找位置,然后补全,在这个位置,直接复制下来
继续找
找到,然后复制下来。
现在没有报错,我们试一下结果对不对。。
完美解决,所以此时我们已经得到了这个正确的js代码,只需要将参数中的ts更改成当前的请求时间戳就行,
这里贴上html代码,你只需要把js部分复制修改即可
1
我们来处理一下此时的python请求,先把第一步确定好。
第一步请求的python代码
import requests
import execjs
ts = int(execjs.compile(open('D:/桌面/pythoncode/new.js', 'r', encoding='utf-8').read()).call('gettime'))json_data = {'pageNo': 1,'pageSize': 40,'total': 5770,'AREACODE': '','M_PROJECT_TYPE': '','KIND': 'GCJS','GGTYPE': '1','PROTYPE': '','timeType': '6','BeginTime': '2022-07-18 00:00:00','EndTime': '2023-01-18 23:59:59','createTime': [],'ts': ts,
}
sign = str(execjs.compile(open('D:/桌面/pythoncode/new.js', 'r', encoding='utf-8').read()).call('main',json_data))
print(sign)
headers = {'Accept': 'application/json, text/plain, */*','Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7','Connection': 'keep-alive','Content-Type': 'application/json;charset=UTF-8','Origin': 'https://ggzyfw.fujian.gov.cn','Referer': 'https://ggzyfw.fujian.gov.cn/business/list/','Sec-Fetch-Dest': 'empty','Sec-Fetch-Mode': 'cors','Sec-Fetch-Site': 'same-origin','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36','portal-sign': sign,'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"',}response = requests.post('https://ggzyfw.fujian.gov.cn/FwPortalApi/Trade/TradeInfo', headers=headers, json=json_data).json()
print(response)
得到请求头加密参数
HEX_CHARS = "0123456789abcdef".split("")
EXTRA = [128, 32768, 8388608, -2147483648]
var buffer = new ArrayBuffer(68);
buffer8 = new Uint8Array(buffer),
blocks = new Uint32Array(buffer)
function Md5(t) {if (t)blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0,this.blocks = blocks,this.buffer8 = buffer8;else if (true) {var n = new ArrayBuffer(68);this.buffer8 = new Uint8Array(n),this.blocks = new Uint32Array(n)} elsethis.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0,this.finalized = this.hashed = !1,this.first = !0
}
Md5.prototype.update = function (t) {if (!this.finalized) {var n, e = typeof t;if ("string" !== e) {if ("object" !== e)throw ERROR;if (null === t)throw ERROR;if (true && t.constructor === ArrayBuffer)t = new Uint8Array(t);else if (!Array.isArray(t) && (!true || !ArrayBuffer.isView(t)))throw ERROR;n = !0}var r, i, o = 0, c = t.length, A = this.blocks, a = this.buffer8;while (o < c) {if (this.hashed && (this.hashed = !1,A[0] = A[16],A[16] = A[1] = A[2] = A[3] = A[4] = A[5] = A[6] = A[7] = A[8] = A[9] = A[10] = A[11] = A[12] = A[13] = A[14] = A[15] = 0),n)if (true)for (i = this.start; o < c && i < 64; ++o)a[i++] = t[o];elsefor (i = this.start; o < c && i < 64; ++o)A[i >> 2] |= t[o] << SHIFT[3 & i++];else if (true)for (i = this.start; o < c && i < 64; ++o)r = t.charCodeAt(o),r < 128 ? a[i++] = r : r < 2048 ? (a[i++] = 192 | r >> 6,a[i++] = 128 | 63 & r) : r < 55296 || r >= 57344 ? (a[i++] = 224 | r >> 12,a[i++] = 128 | r >> 6 & 63,a[i++] = 128 | 63 & r) : (r = 65536 + ((1023 & r) << 10 | 1023 & t.charCodeAt(++o)),a[i++] = 240 | r >> 18,a[i++] = 128 | r >> 12 & 63,a[i++] = 128 | r >> 6 & 63,a[i++] = 128 | 63 & r);elsefor (i = this.start; o < c && i < 64; ++o)r = t.charCodeAt(o),r < 128 ? A[i >> 2] |= r << SHIFT[3 & i++] : r < 2048 ? (A[i >> 2] |= (192 | r >> 6) << SHIFT[3 & i++],A[i >> 2] |= (128 | 63 & r) << SHIFT[3 & i++]) : r < 55296 || r >= 57344 ? (A[i >> 2] |= (224 | r >> 12) << SHIFT[3 & i++],A[i >> 2] |= (128 | r >> 6 & 63) << SHIFT[3 & i++],A[i >> 2] |= (128 | 63 & r) << SHIFT[3 & i++]) : (r = 65536 + ((1023 & r) << 10 | 1023 & t.charCodeAt(++o)),A[i >> 2] |= (240 | r >> 18) << SHIFT[3 & i++],A[i >> 2] |= (128 | r >> 12 & 63) << SHIFT[3 & i++],A[i >> 2] |= (128 | r >> 6 & 63) << SHIFT[3 & i++],A[i >> 2] |= (128 | 63 & r) << SHIFT[3 & i++]);this.lastByteIndex = i,this.bytes += i - this.start,i >= 64 ? (this.start = i - 64,this.hash(),this.hashed = !0) : this.start = i}return this.bytes > 4294967295 && (this.hBytes += this.bytes / 4294967296 << 0,this.bytes = this.bytes % 4294967296),this}
},Md5.prototype.finalize = function () {if (!this.finalized) {this.finalized = !0;var t = this.blocks, n = this.lastByteIndex;t[n >> 2] |= EXTRA[3 & n],n >= 56 && (this.hashed || this.hash(),t[0] = t[16],t[16] = t[1] = t[2] = t[3] = t[4] = t[5] = t[6] = t[7] = t[8] = t[9] = t[10] = t[11] = t[12] = t[13] = t[14] = t[15] = 0),t[14] = this.bytes << 3,t[15] = this.hBytes << 3 | this.bytes >>> 29,this.hash()}},Md5.prototype.hash = function () {var t, n, e, r, i, o, c = this.blocks;this.first ? (t = c[0] - 680876937,t = (t << 7 | t >>> 25) - 271733879 << 0,r = (-1732584194 ^ 2004318071 & t) + c[1] - 117830708,r = (r << 12 | r >>> 20) + t << 0,e = (-271733879 ^ r & (-271733879 ^ t)) + c[2] - 1126478375,e = (e << 17 | e >>> 15) + r << 0,n = (t ^ e & (r ^ t)) + c[3] - 1316259209,n = (n << 22 | n >>> 10) + e << 0) : (t = this.h0,n = this.h1,e = this.h2,r = this.h3,t += (r ^ n & (e ^ r)) + c[0] - 680876936,t = (t << 7 | t >>> 25) + n << 0,r += (e ^ t & (n ^ e)) + c[1] - 389564586,r = (r << 12 | r >>> 20) + t << 0,e += (n ^ r & (t ^ n)) + c[2] + 606105819,e = (e << 17 | e >>> 15) + r << 0,n += (t ^ e & (r ^ t)) + c[3] - 1044525330,n = (n << 22 | n >>> 10) + e << 0),t += (r ^ n & (e ^ r)) + c[4] - 176418897,t = (t << 7 | t >>> 25) + n << 0,r += (e ^ t & (n ^ e)) + c[5] + 1200080426,r = (r << 12 | r >>> 20) + t << 0,e += (n ^ r & (t ^ n)) + c[6] - 1473231341,e = (e << 17 | e >>> 15) + r << 0,n += (t ^ e & (r ^ t)) + c[7] - 45705983,n = (n << 22 | n >>> 10) + e << 0,t += (r ^ n & (e ^ r)) + c[8] + 1770035416,t = (t << 7 | t >>> 25) + n << 0,r += (e ^ t & (n ^ e)) + c[9] - 1958414417,r = (r << 12 | r >>> 20) + t << 0,e += (n ^ r & (t ^ n)) + c[10] - 42063,e = (e << 17 | e >>> 15) + r << 0,n += (t ^ e & (r ^ t)) + c[11] - 1990404162,n = (n << 22 | n >>> 10) + e << 0,t += (r ^ n & (e ^ r)) + c[12] + 1804603682,t = (t << 7 | t >>> 25) + n << 0,r += (e ^ t & (n ^ e)) + c[13] - 40341101,r = (r << 12 | r >>> 20) + t << 0,e += (n ^ r & (t ^ n)) + c[14] - 1502002290,e = (e << 17 | e >>> 15) + r << 0,n += (t ^ e & (r ^ t)) + c[15] + 1236535329,n = (n << 22 | n >>> 10) + e << 0,t += (e ^ r & (n ^ e)) + c[1] - 165796510,t = (t << 5 | t >>> 27) + n << 0,r += (n ^ e & (t ^ n)) + c[6] - 1069501632,r = (r << 9 | r >>> 23) + t << 0,e += (t ^ n & (r ^ t)) + c[11] + 643717713,e = (e << 14 | e >>> 18) + r << 0,n += (r ^ t & (e ^ r)) + c[0] - 373897302,n = (n << 20 | n >>> 12) + e << 0,t += (e ^ r & (n ^ e)) + c[5] - 701558691,t = (t << 5 | t >>> 27) + n << 0,r += (n ^ e & (t ^ n)) + c[10] + 38016083,r = (r << 9 | r >>> 23) + t << 0,e += (t ^ n & (r ^ t)) + c[15] - 660478335,e = (e << 14 | e >>> 18) + r << 0,n += (r ^ t & (e ^ r)) + c[4] - 405537848,n = (n << 20 | n >>> 12) + e << 0,t += (e ^ r & (n ^ e)) + c[9] + 568446438,t = (t << 5 | t >>> 27) + n << 0,r += (n ^ e & (t ^ n)) + c[14] - 1019803690,r = (r << 9 | r >>> 23) + t << 0,e += (t ^ n & (r ^ t)) + c[3] - 187363961,e = (e << 14 | e >>> 18) + r << 0,n += (r ^ t & (e ^ r)) + c[8] + 1163531501,n = (n << 20 | n >>> 12) + e << 0,t += (e ^ r & (n ^ e)) + c[13] - 1444681467,t = (t << 5 | t >>> 27) + n << 0,r += (n ^ e & (t ^ n)) + c[2] - 51403784,r = (r << 9 | r >>> 23) + t << 0,e += (t ^ n & (r ^ t)) + c[7] + 1735328473,e = (e << 14 | e >>> 18) + r << 0,n += (r ^ t & (e ^ r)) + c[12] - 1926607734,n = (n << 20 | n >>> 12) + e << 0,i = n ^ e,t += (i ^ r) + c[5] - 378558,t = (t << 4 | t >>> 28) + n << 0,r += (i ^ t) + c[8] - 2022574463,r = (r << 11 | r >>> 21) + t << 0,o = r ^ t,e += (o ^ n) + c[11] + 1839030562,e = (e << 16 | e >>> 16) + r << 0,n += (o ^ e) + c[14] - 35309556,n = (n << 23 | n >>> 9) + e << 0,i = n ^ e,t += (i ^ r) + c[1] - 1530992060,t = (t << 4 | t >>> 28) + n << 0,r += (i ^ t) + c[4] + 1272893353,r = (r << 11 | r >>> 21) + t << 0,o = r ^ t,e += (o ^ n) + c[7] - 155497632,e = (e << 16 | e >>> 16) + r << 0,n += (o ^ e) + c[10] - 1094730640,n = (n << 23 | n >>> 9) + e << 0,i = n ^ e,t += (i ^ r) + c[13] + 681279174,t = (t << 4 | t >>> 28) + n << 0,r += (i ^ t) + c[0] - 358537222,r = (r << 11 | r >>> 21) + t << 0,o = r ^ t,e += (o ^ n) + c[3] - 722521979,e = (e << 16 | e >>> 16) + r << 0,n += (o ^ e) + c[6] + 76029189,n = (n << 23 | n >>> 9) + e << 0,i = n ^ e,t += (i ^ r) + c[9] - 640364487,t = (t << 4 | t >>> 28) + n << 0,r += (i ^ t) + c[12] - 421815835,r = (r << 11 | r >>> 21) + t << 0,o = r ^ t,e += (o ^ n) + c[15] + 530742520,e = (e << 16 | e >>> 16) + r << 0,n += (o ^ e) + c[2] - 995338651,n = (n << 23 | n >>> 9) + e << 0,t += (e ^ (n | ~r)) + c[0] - 198630844,t = (t << 6 | t >>> 26) + n << 0,r += (n ^ (t | ~e)) + c[7] + 1126891415,r = (r << 10 | r >>> 22) + t << 0,e += (t ^ (r | ~n)) + c[14] - 1416354905,e = (e << 15 | e >>> 17) + r << 0,n += (r ^ (e | ~t)) + c[5] - 57434055,n = (n << 21 | n >>> 11) + e << 0,t += (e ^ (n | ~r)) + c[12] + 1700485571,t = (t << 6 | t >>> 26) + n << 0,r += (n ^ (t | ~e)) + c[3] - 1894986606,r = (r << 10 | r >>> 22) + t << 0,e += (t ^ (r | ~n)) + c[10] - 1051523,e = (e << 15 | e >>> 17) + r << 0,n += (r ^ (e | ~t)) + c[1] - 2054922799,n = (n << 21 | n >>> 11) + e << 0,t += (e ^ (n | ~r)) + c[8] + 1873313359,t = (t << 6 | t >>> 26) + n << 0,r += (n ^ (t | ~e)) + c[15] - 30611744,r = (r << 10 | r >>> 22) + t << 0,e += (t ^ (r | ~n)) + c[6] - 1560198380,e = (e << 15 | e >>> 17) + r << 0,n += (r ^ (e | ~t)) + c[13] + 1309151649,n = (n << 21 | n >>> 11) + e << 0,t += (e ^ (n | ~r)) + c[4] - 145523070,t = (t << 6 | t >>> 26) + n << 0,r += (n ^ (t | ~e)) + c[11] - 1120210379,r = (r << 10 | r >>> 22) + t << 0,e += (t ^ (r | ~n)) + c[2] + 718787259,e = (e << 15 | e >>> 17) + r << 0,n += (r ^ (e | ~t)) + c[9] - 343485551,n = (n << 21 | n >>> 11) + e << 0,this.first ? (this.h0 = t + 1732584193 << 0,this.h1 = n - 271733879 << 0,this.h2 = e - 1732584194 << 0,this.h3 = r + 271733878 << 0,this.first = !1) : (this.h0 = this.h0 + t << 0,this.h1 = this.h1 + n << 0,this.h2 = this.h2 + e << 0,this.h3 = this.h3 + r << 0)},Md5.prototype.hex = function () {this.finalize();var t = this.h0, n = this.h1, e = this.h2, r = this.h3;return HEX_CHARS[t >> 4 & 15] + HEX_CHARS[15 & t] + HEX_CHARS[t >> 12 & 15] + HEX_CHARS[t >> 8 & 15] + HEX_CHARS[t >> 20 & 15] + HEX_CHARS[t >> 16 & 15] + HEX_CHARS[t >> 28 & 15] + HEX_CHARS[t >> 24 & 15] + HEX_CHARS[n >> 4 & 15] + HEX_CHARS[15 & n] + HEX_CHARS[n >> 12 & 15] + HEX_CHARS[n >> 8 & 15] + HEX_CHARS[n >> 20 & 15] + HEX_CHARS[n >> 16 & 15] + HEX_CHARS[n >> 28 & 15] + HEX_CHARS[n >> 24 & 15] + HEX_CHARS[e >> 4 & 15] + HEX_CHARS[15 & e] + HEX_CHARS[e >> 12 & 15] + HEX_CHARS[e >> 8 & 15] + HEX_CHARS[e >> 20 & 15] + HEX_CHARS[e >> 16 & 15] + HEX_CHARS[e >> 28 & 15] + HEX_CHARS[e >> 24 & 15] + HEX_CHARS[r >> 4 & 15] + HEX_CHARS[15 & r] + HEX_CHARS[r >> 12 & 15] + HEX_CHARS[r >> 8 & 15] + HEX_CHARS[r >> 20 & 15] + HEX_CHARS[r >> 16 & 15] + HEX_CHARS[r >> 28 & 15] + HEX_CHARS[r >> 24 & 15]},Md5.prototype.toString = Md5.prototype.hex,Md5.prototype.digest = function () {this.finalize();var t = this.h0, n = this.h1, e = this.h2, r = this.h3;return [255 & t, t >> 8 & 255, t >> 16 & 255, t >> 24 & 255, 255 & n, n >> 8 & 255, n >> 16 & 255, n >> 24 & 255, 255 & e, e >> 8 & 255, e >> 16 & 255, e >> 24 & 255, 255 & r, r >> 8 & 255, r >> 16 & 255, r >> 24 & 255]},Md5.prototype.array = Md5.prototype.digest,Md5.prototype.arrayBuffer = function () {this.finalize();var t = new ArrayBuffer(16), n = new Uint32Array(t);return n[0] = this.h0,n[1] = this.h1,n[2] = this.h2,n[3] = this.h3,t},Md5.prototype.buffer = Md5.prototype.arrayBuffer,Md5.prototype.base64 = function () {for (var t, n, e, r = "", i = this.array(), o = 0; o < 15;)t = i[o++],n = i[o++],e = i[o++],r += BASE64_ENCODE_CHAR[t >>> 2] + BASE64_ENCODE_CHAR[63 & (t << 4 | n >>> 4)] + BASE64_ENCODE_CHAR[63 & (n << 2 | e >>> 6)] + BASE64_ENCODE_CHAR[63 & e];return t = i[o],r += BASE64_ENCODE_CHAR[t >>> 2] + BASE64_ENCODE_CHAR[t << 4 & 63] + "==",r}
function s(t, e) {return t.toString().toUpperCase() > e.toString().toUpperCase() ? 1 : t.toString().toUpperCase() == e.toString().toUpperCase() ? 0 : -1
}
function l(t) {for (var e = Object.keys(t).sort(s), n = "", a = 0; a < e.length; a++)if (void 0 !== t[e[a]])if (t[e[a]] && t[e[a]] instanceof Object || t[e[a]] instanceof Array) {var i = JSON.stringify(t[e[a]]);n += e[a] + i} elsen += e[a] + t[e[a]];return n
}
function d(t) {for (var e in t)"" !== t[e] && void 0 !== t[e] || delete t[e];var n = "B3978D054A72A7002063637CCDF6B2E5" + l(t);return new Md5(!0).update(n)['hex']()
}
function gettime(){d1 = ((new Date).getTime())return d1
}function main(dictData) {return d(dictData)
}
准备解决得到的加密数据。
这个纯靠经验,直接搜索,decrypt(),这个东西是js的一种解密的密钥
出现两个,我们现在先看第一个。
打断点调试
执行到这个位置的时候,我们输出一下a.tostring(),主要还是t的数据格式格式跟返回的data太像了
发现,这个结果是我们需要的数据
直接复制这段函数,使用crypto-js,来模拟一下检查是不是aes的(名字中存在)
将缺少的参数补上,这里还是控制台输出r["e"] r["j"]
返回参数解密
const Crypto = require('crypto-js')var c = 'EB444973714E4A40876CE66BE45D5930'
var b = 'B5A8904209931867'
function decrypt(t) {var e = Crypto.enc.Utf8.parse(c), n = Crypto.enc.Utf8.parse(b), a = Crypto.AES.decrypt(t, e, {iv: n,mode: Crypto.mode.CBC,padding: Crypto.pad.Pkcs7});return a.toString(Crypto.enc.Utf8)
}
我们可以发现返回值符合预期结果,所以这个js文件处理加密的数据是正确的
最终的py代码
import requests
import execjs
ts = int(execjs.compile(open('D:\桌面\pythoncode\得到加密参数.js', 'r', encoding='utf-8').read()).call('gettime'))json_data = {'pageNo': 1,'pageSize': 40,'total': 5770,'AREACODE': '','M_PROJECT_TYPE': '','KIND': 'GCJS','GGTYPE': '1','PROTYPE': '','timeType': '6','BeginTime': '2022-07-18 00:00:00','EndTime': '2023-01-18 23:59:59','createTime': [],'ts': ts,
}
sign = str(execjs.compile(open('D:\桌面\pythoncode\得到加密参数.js', 'r', encoding='utf-8').read()).call('main',json_data))
print(sign)
headers = {'Accept': 'application/json, text/plain, */*','Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7','Connection': 'keep-alive','Content-Type': 'application/json;charset=UTF-8','Origin': 'https://ggzyfw.fujian.gov.cn','Referer': 'https://ggzyfw.fujian.gov.cn/business/list/','Sec-Fetch-Dest': 'empty','Sec-Fetch-Mode': 'cors','Sec-Fetch-Site': 'same-origin','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36','portal-sign': sign,'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"',}response = requests.post('https://ggzyfw.fujian.gov.cn/FwPortalApi/Trade/TradeInfo', headers=headers, json=json_data).json()
data = response["Data"]
ctx = execjs.compile(open('D:\桌面\pythoncode\解密得到的数据.js', 'r', encoding='utf-8').read()).call('decrypt', data)
print(ctx)
效果展示
批量下载只需要修改参数即可,留个赞!