python爬虫HMAC加密案例:某企业信息查询网站

声明:
该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关

一、找出需要加密的参数
  1. js运行 atob(‘aHR0cHM6Ly93d3cucWNjLmNvbS93ZWIvc2VhcmNoP2tleT0lRTQlQjglODclRTglQkUlQkUlRTklOUIlODYlRTUlOUIlQTI=’) 拿到网址,F12打开调试工具,点击分页找到 search/searchMultit 请求,鼠标右击请求找到Copy>Copy as cUrl(cmd)
  2. 打开网站:https://spidertools.cn/#/curl2Request,把拷贝好的curl转成python代码
    在这里插入图片描述
  3. 新建qichacha.py文件,把代码复制到该文件内,把请求中的参数拷贝给data,请求中的data参数换成json,运行文件,发现请求成功并成功获取到数据
    在这里插入图片描述
  4. 然后把代码中header、cookie注释调试后会发现一个虽生成的header、QCCSESSID是加密的
    在这里插入图片描述
  5. 在请求cookies中分析得知 ,QCCSESSID是后端生成的可以不用管
    在这里插入图片描述
二、定位参数加密位置
  1. 由于加密的header是动态生成的,显然使用关键字搜索无法定位到,直接切换到sources,添加XHR拦截 search/searchMulti
    在这里插入图片描述
  2. 一直点击跳到下一个函数,会看到作用域header里面已经没有请求头,在代码里又看到熟悉的参数 x-pid,可以尝试的分析里面的代码
    在这里插入图片描述
  3. 鼠标悬浮到 o.default 找到该函数的位置,会发现里面有个header 赋值的代码,在该代码打上断点
    在这里插入图片描述
  4. 结束此次断点调试,点击分页重新发送请求,鼠标悬浮到 i 上发现有随机生成的 header,并且很容易就找到 i = (0, a.default)(t, e.data),l = (0, r.default)(t, e.data, (0, s.default)()),i 是header的key,l是header的value
    在这里插入图片描述
三、扣出加密代码
  1. 创建qichacha.js文件,用于放扣出的js代码
  2. 先把 header 的 key 和 value 扣出来,i = (0, a.default)(t, e.data),l = (0, r.default)(t, e.data, (0, s.default)()),把 t、e.data 在控制台打印出来会发现 t 是请求路径,e.data是请求参数
    在这里插入图片描述在这里插入图片描述
  3. 扣出加密header的key:i = (0, a.default)(t, e.data)
  • 根据第二步已经知道 t 是请求路径,e.data是请求参数,所以只要扣出 a.default 就行, 把 a.default 打印出来会发现,a.default是方法
    在这里插入图片描述
  • 点击打印出的 a.default 方法,会快速找到该方法的位置,会发现只有 o.default、a.default是值得注意的方法,其他都是js语法,在方法内部打上断点,并把 s 方法扣到qichacha.js,把 a.default 换成 s
    在这里插入图片描述在这里插入图片描述
  • 开始扣出 s 方法中的 o.default:结束本次调试,点击分页重新发送请求,鼠标悬浮到 o.default,点击蓝色部分找到该方法,会再次发现 o.default 方法在该代码打上断点,并把 r 方法 js扣到qichacha.js,并把 s 中 o.default 替换成 r
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
  • 结束本次断点,点击分页重新发送请求,一直点击跳到断店调试,看到 e 是路径+参数的字符串时,鼠标悬浮到 r 方法中的 o.default,点击蓝色部分找到该方法,会发现是个HMAC加密
    在这里插入图片描述在这里插入图片描述
  • 分析是哪种 HMAC 加密,在控制台分别打印出:加密数据 e、加密密钥 t、解密结果(0,o.default)(e, t).toString(),打开网站 https://www.dute.org/hmac?ref=search,输入密钥 、加密数据,加密算法是 HMAC SHA 512
    在这里插入图片描述在这里插入图片描述
  • 根据 HMAC SHA 512 算法完成 r 方法,经过测试相同的加密数据和加密密钥,解密结果相同,至此 s 方法中的 o.default 完全扣出,至此 s 方法中的 o.defaul 完全扣出
    在这里插入图片描述
  • 开始扣出 s 方法中的 a.default:分析 s 方法中的 a.default,点击蓝色部分找到该方法,会发现是个 r 方法,里面值得注意的是 o.default,其他都是js语法,在 for循环打上断点,,并把 r 方法 js扣到 qichacha.js 因为和之前 r 方法冲突命名为 r1,并把 s 中 a.default 替换成r1
    在这里插入图片描述在这里插入图片描述
  • 结束本次断点,点击分页重新发送请求,一直点击跳到断店调试,看到 r 方法停止调试,在控制台输出 o.default,把打印结果复制出来,补全 r1 方法,至此 s 方法中的 a.default 完全扣出
    在这里插入图片描述
  • 验证结果 i = (0, a.default)(t, e.data),删除除了 e.headers[i] = l 之外的其他断点,点击第一页发送请求,把 i 打印控制台,再运行 qichacha.js 文件打印 i,对比两个 i 会发现两个之一样
    在这里插入图片描述在这里插入图片描述
  1. 扣出加密header的key:l = (0, r.default)(t, e.data, (0, s.default)())
  • 根据第二步已经知道 t 是请求路径,e.data是请求参数,所以只要扣出 r.default 、r.default 就行
  • 点击分页重新发送请求,鼠标悬浮到 s.default,点击蓝色部分找到该方法,会发现 _default 方法,该方法中都是 js 语法,只需把该函数拷贝出来就行,拷贝出来后命名为 s1,把 s.default 换成 s1
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
  • 测试 s1 方法会发现,报 windows.tid 为 undefined的错误,切换到提示工具 Elements ,全局搜索 windows.tid 会发现该值是固定的值,把该值赋值下来替换 s1 并删除 s1
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
  • 开始扣出 r.default 方法:鼠标悬浮到 r.defaul,点击蓝色部分找到该方法,会发现一个 s 方法,会发现只有 o.default、a.default是值得注意的方法,其他都是js语法,在方法内部打上断点,并把 s 方法扣到qichacha.js 命名为 s1,把 r.default 换成 s1
    在这里插入图片描述在这里插入图片描述
  • 仔细分析 s1 会发现和之前的 s 方法类似,可以先试着,把 s1 方法中的 o.default、a.default 替换成之前的 r、r1
    在这里插入图片描述
  • 测试 s1 方法:把 n、i、(0,o.default)(n + “pathString” + i + t, (0,a.default)(n)) 输出控制台,把 n、i、tid值传给 s1 并打印出来,发现同样的参数,得到值一样,说明 s1 内部的 o.default、a.default 确实是 r、r1,结束断点调试
    在这里插入图片描述
四、验证结果
  1. 修改qichacha.js,把 t、par作为参数传给 main 方法,并运行文件,打印出生成的 key、value
    在这里插入图片描述
  2. 点击第一页重新请求,在控制台输出 i、l,对比发现值都是一样的
    在这里插入图片描述
  3. 修改 qichacha.py 文件,运行文件,数据获取成功
    在这里插入图片描述
五、最终代码
  1. qichacha.js
var cryptoJs = require('crypto-js')var r = function (e, t) {var hmacSha512 = cryptoJs.HmacSHA512(e, t);return hmacSha512.toString()
};var r1 = function () {var o = {"n": 20,"codes": {"0": "W","1": "l","2": "k","3": "B","4": "Q","5": "g","6": "f","7": "i","8": "i","9": "r","10": "v","11": "6","12": "A","13": "K","14": "N","15": "k","16": "4","17": "L","18": "1","19": "8"}};for (var e = (arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "/").toLowerCase(), t = e + e, n = "", i = 0; i < t.length; ++i) {var a = t[i].charCodeAt() % o.n;n += o.codes[a]}return n
};var s = function () {var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, t = (arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "/").toLowerCase(), n = JSON.stringify(e).toLowerCase();return r(t + n, r1(t)).toLowerCase().substr(8, 20)
};var s1 = function () {var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, t = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "", n = (arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "/").toLowerCase(), i = JSON.stringify(e).toLowerCase();return r(n + "pathString" + i + t, r1(n))
};function main(t, par) {var i = s(t, par);var l = s1(t, par, 'f7d239d312096b665fd9e4a46e603592');return {key: i, value: l}
}var t = '/api/search/searchmulti';
var par = {"searchKey": "万达集团","pageIndex": 1,"pageSize": 20,
}
console.log(main(t,par))
  1. qichacha.py
import requests
import execjs
import furlheaders = {"authority": "www.qcc.com","accept": "application/json, text/plain, */*","accept-language": "zh-CN,zh;q=0.9","cache-control": "no-cache","content-type": "application/json","origin": "https://www.qcc.com","pragma": "no-cache","referer": "https://www.qcc.com/web/search?key=^%^E4^%^B8^%^87^%^E8^%^BE^%^BE^%^E9^%^9B^%^86^%^E5^%^9B^%^A2","sec-ch-ua": "^\\^Google","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "^\\^Windows^^","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/119.0.0.0 Safari/537.36","x-requested-with": "XMLHttpRequest","x-pid": "30ccc65659628b892fb5c1c99a083a95",# "43d930d400d14394164a": "87ae6559513fa06d04d868f1a98d6e48637c09c76415caadecdd28f8e52f9912bca862cce00619ae312b20a57701dcf7858063dd9bb071fad27c01076e24be9d",
}
cookies = {"QCCSESSID": "eaa3818b5a849d53ca70e37dac","qcc_did": "fe88cac5-6065-4d4d-bdc6-f642aea5386b"
}
url = "https://www.qcc.com/api/search/searchMulti"
data = {"searchKey": "万达集团","pageIndex": 2,"pageSize": 20
}with open('qichacha.js','r') as js_file:js = execjs.compile(js_file.read())url_info = furl.furl(url)get_headers = js.call('main',str(url_info.path),data)headers[get_headers['key']] = get_headers['value']print(headers)response = requests.post(url, headers=headers, cookies=cookies, json=data)print(response.text)print(response)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/208608.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

广告机/商业显示屏_基于MT878安卓主板方案

安卓主板在广告机领域扮演着重要的角色。无论是在商场、车站、酒店、电梯、机场还是高铁站&#xff0c;LED广告机广泛应用&#xff0c;并通过不同方式进行播放和管理。 广告机/商业显示屏_基于MT878安卓主板方案 基于MT8788安卓主板方案的广告机采用了联发科MT8788八核芯片方案…

nint和Pattern matching介绍(C#)

nint 最近看C# 9.0时&#xff0c;发现一个有意思的关键词&#xff0c;就是nint&#xff0c;第一次看到这个&#xff0c;于是好奇心爆棚&#xff0c;就去实际操作了一下。 nint i 1000; Console.WriteLine("i{0}", i);实际结果与int的结果是一样的&#xff0c;那为什…

HCIP-四、MUX-vlanSuper-vlan+端口安全

四、MUX-vlan&Super-vlan端口安全 MUX-vlan实验拓扑实验需求及解法1. 在SW1/2/3分别创建vlan10 20 30 402. SW1/2/3之间使用trunk链路&#xff0c;仅允许vlan10 20 30 40 通过。3. SW与PC/Server之间使用access链路。4. ping验证&#xff1a; Super-vlan端口安全实验拓扑实…

实在智能携“TARS大模型”入选“2023中国数据智能产业AI大模型先锋企业”

近日&#xff0c;由数据猿与上海大数据联盟联合主办的“2023企业数智化转型升级发展论坛”在上海圆满收官。 论坛颁奖典礼上&#xff0c;《2023中国数据智能产业AI大模型先锋企业》等六大榜单正式揭晓&#xff0c;旨在表彰在AI领域为数智化升级取得卓越成就和突出贡献的企业&am…

基于C#实现优先队列

一、堆结构 1.1性质 堆是一种很松散的序结构树&#xff0c;只保存了父节点和孩子节点的大小关系&#xff0c;并不规定左右孩子的大小&#xff0c;不像排序树那样严格&#xff0c;又因为堆是一种完全二叉树&#xff0c;设节点为 i,则 i/2 是 i 的父节点&#xff0c;2i 是 i 的…

Doris动态分区(十四)

动态分区是在 Doris 0.12 版本中引入的新功能。旨在对表级别的分区实现生命周期管理&#xff08;TTL&#xff09;&#xff0c;减少用户的使用负担。 目前实现了动态添加分区及动态删除分区的功能。动态分区只支持 Range 分区。 原理 在某些使用场景下&#xff0c;用户会将表…

【中间件】服务化中间件理论intro

中间件middleware 内容管理 intro服务化middleware架构注册中心intro服务治理系统intro 本文主要intro服务化中间件的探讨 去年cfeng写了一篇博客走马观花般阐述了Spring Cloud下面的各种中间件&#xff0c;连深入使用都谈不上&#xff0c;只能说intro&#xff0c;在实际work中…

LabVIEW中将SMU信号连接到PXI背板触发线

LabVIEW中将SMU信号连接到PXI背板触发线 本文介绍如何将信号从PXI&#xff08;e&#xff09;SMU卡路由到PXI&#xff08;e&#xff09;机箱上的背板触发线。该过程涉及使用NI-DCPowerVI将SMU信号导出到PXI_TRIG线上。 在继续操作之前&#xff0c;请确保在开发PC上安装了兼容版…

python二叉树链树_树的链式存储结构

二叉链树是一种树状数据结构&#xff0c;其中每个节点最多有两个子节点&#xff0c;分别称为左子节点和右子节点。每个节点包含一个数据元素和指向其左右子节点的指针。二叉链树可以是空树&#xff0c;也可以是具有以下特点的非空树&#xff1a; 1. 每个节点最多有两个子节点。…

minio集群部署(k8s内)

一、前言 minio的部署有几种方式&#xff0c;分别是单节点单磁盘&#xff0c;单节点多磁盘&#xff0c;多节点多磁盘三种方式&#xff0c;本次部署使用多节点多磁盘的方式进行部署&#xff0c;minio集群多节点部署最低要求需要4个节点&#xff0c;集群扩容时也是要求扩容的节点…

【腾讯云云上实验室-向量数据库】腾讯云VectorDB:深度学习场景下的新一代数据存储方案

引言 ​  在深度学习领域的实践中&#xff0c;一般会涉及到向量化处理的数据&#xff0c;如图像、文本、音频等&#xff0c;这些数据的存储和检索对于许多深度学习任务至关重要。传统的关系型数据库和NoSQL数据库在存储和检索这类大规模向量数据时&#xff0c;通常不能满足高…

shell 条件语句

目录 测试 test测试文件的表达式 是否成立 格式 选项 比较整数数值 格式 选项 字符串比较 常用的测试操作符 格式 逻辑测试 格式 且 &#xff08;全真才为真&#xff09; 或 &#xff08;一真即为真&#xff09; 常见条件 双中括号 [[ expression ]] 用法 &…