10_某集团RSA长加密

Date
Jan 14, 2023
Created
Mar 2, 2024 02:50 PM
Tags
JS逆向实战

声明

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!
由于本网站较为特殊 目标网站加密与其他稍有不同

目标网站

68747470733a2f2f65632e6d696e6d6574616c732e636f6d2e636e2f6f70656e2f686f6d652f70757263686173652d696e666f2f3f746162496e6465783d31

需求

爬取所有的列表页 标题 时间 url 以及详情页内容

分析

在爬取列表页时 会发现 有两个请求,说明有两个请求是一起发送的。
notion image

第一个请求

notion image
可以发现这个请求 直接发起post 请求就可以拿到数据

第二个请求

notion image
可以发现请求体是一串代码 估计和第一个参数有关

寻找参数

这个网站是几个月前爬的,目前很多JS以及混淆了,所以本篇文章只记录自己的爬取,不提供代码了 这里提供网站混淆前的JS代码
function hex2b64(d) { let b; let e; let a = ''; const b64map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; const b64pad = '='; for (b = 0; b + 3 <= d.length; b += 3) { e = parseInt(d.substring(b, b + 3), 16); a += b64map.charAt(e >> 6) + b64map.charAt(e & 63); } if (b + 1 === d.length) { e = parseInt(d.substring(b, b + 1), 16); a += b64map.charAt(e << 2); } else { if (b + 2 === d.length) { e = parseInt(d.substring(b, b + 2), 16); a += b64map.charAt(e >> 2) + b64map.charAt((e & 3) << 4); } } while ((a.length & 3) > 0) { a += b64pad; } return a; } //重新定义分段加密方法(加密参数过长) JSEncrypt.prototype.encryptLong = function (string) { const k = this.getKey(), maxLength = ((k.n.bitLength() + 7) >> 3) - 11; try { let lt = '', ct = ''; if (string.length > maxLength) { lt = string.match(/.{1,50}/g); lt.forEach(entry => { const t1 = k.encrypt(entry); ct += t1; }); return hex2b64(ct); } const t = k.encrypt(string), y = hex2b64(t); return y; } catch (ex) { return ex; } }; //导出加密方法 function getDataByEncrypted(requestData = {}) { const rsaInstance = new JSEncrypt(); rsaInstance.setPublicKey(""); const newRequestData = { ...requestData, sign: md5(JSON.stringify(requestData)), timeStamp: +new Date(), }; const encryptionData = JSEncrypt.prototype.encryptLong(JSON.stringify(newRequestData)); return encryptionData; }
根据代码可知 这串代码是通过JS来进行的加密 公钥就是上文所指的第一个请求请求到的结果 私钥就是第二个请求反加密的值 也就是newRequestData
知道了公钥和私钥,我们可以自己通过代码解出来了。

注意

这里有个小坑 如果用Python 去改写 JSON.stringify (Javascript) 和 json.dumps (Python) 不等价 不同之处在于 json.dumps 默认应用一些小的 pretty-print ,但 JSON.stringify 没有。
要删除所有空格,例如 JSON.stringify,您需要 specify the separators .
json_text = json.dumps(source, separators=(',', ':'))