爬虫逆向sm3和sm4 加密 案例

注意!!!!某XX网站逆向实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!!

案例--aHR0cDovLzExMS41Ni4xNDIuMTM6MTgwODgvc3Vic2lkeU9wZW4=

第一步:分析页面和请求方式

通过查看请求参数和响应内容,均为加密数据。最后的加密方式非AES和DES类型。本文主要分享案例中的sm4和sm3 加密

第二步:请求页面并分析请求

请求参数

headers 内容

响应内容

可以看出是均为密文

第三步:打断点逆向解析

在【search】里搜索 sign,通过观察关键信息得到以下即可(至于为啥能找到,自己悟吧,目前我能力有限无法用言语表达,全是命[一脸无奈]),可以看到headers 里加密的三个参数均能看到。sign, timestamp,source

第四步:分析加密方式

通过第三步,可以看到断点后重新请求,能够看出 e 和 t 很像参数,但不是很确定,可以先在控制台打印看一下。可以看出很像,但不确定,可以放置。将sign 生成的方法进行解析。可以看出 使用了s() 方法和 l()方法 ,注意s(t)返回的值要转成大写。

s()方法可以看出使用了sm3的加密方式

l() 方法可以看出使用sm4加密,同时可以看到有个 o 的参数,且参数为常量(别问我为啥,我也说不好,全凭感觉[一脸无奈]),注意注意d() 方法是sm4解密(别问,问就是自己想)

如果把上述代码扣下来会发现r.encrypt() 是个方法,且m() 也是个方法。把我所说的都扣下来基本就妥了。加密的过程就是这样。基本headers内加密参数就解决了

参数加密解析。sign 的断点页面,如下操作,堆栈那块选择上一步。就可以看到请求参数了。可以看到是 h()方法 ,正是一开始解析sign时 部分了。因此e的原本内容是 那一大串dict序列化的 内容(这部分请有缘人自己解析吧,基本复述上述步骤)

第五步:上代码

# -*- coding:utf-8 -*-
# @Time : 2024/3/16 17:39
# @Author: 水兵没月
# @File : XXX解析.py
# @Software: PyCharm
import execjs
from gmssl import sm4, sm3
# 读取JS文件
with open('./XX-解密.js', 'r', encoding='utf-8')as f:files = f.readlines()
f.close()
files = ''.join(files)
ctx = execjs.compile(files)
# 国密 SM3加密
def sm3_hash(message: str):"""国密sm3加密:param message: 消息值,bytes类型:return: 哈希值"""msg_list = [i for i in bytes(message.encode('UTF-8'))]hash_hex = sm3.sm3_hash(msg_list).upper()return hash_hexdef sm4_jiami(t):result = ctx.call('jiami', t)return resultdef sm4_jiemi(t):result = ctx.call('jiemi', t)return result
/* =====================
#@Time : 2024/3/16 17:44
#@Author: 水兵没月
#@File : XX-解密.py
#@Software: PyCharm
=======================*/// &key=HD7232D2AAAKA@978D8723H211?IER&6const e = 0, r = 32, i = 16, o = [214, 144, 233, 254, 204, 225, 61, 183, 22, 182, 20, 194, 40, 251, 44, 5, 43, 103, 154, 118, 42, 190, 4, 195, 170, 68, 19, 38, 73, 134, 6, 153, 156, 66, 80, 244, 145, 239, 152, 122, 51, 84, 11, 67, 237, 207, 172, 98, 228, 179, 28, 169, 201, 8, 232, 149, 128, 223, 148, 250, 117, 143, 63, 166, 71, 7, 167, 252, 243, 115, 23, 186, 131, 89, 60, 25, 230, 133, 79, 168, 104, 107, 129, 178, 113, 100, 218, 139, 248, 235, 15, 75, 112, 86, 157, 53, 30, 36, 14, 94, 99, 88, 209, 162, 37, 34, 124, 59, 1, 33, 120, 135, 212, 0, 70, 87, 159, 211, 39, 82, 76, 54, 2, 231, 160, 196, 200, 158, 234, 191, 138, 210, 64, 199, 56, 181, 163, 247, 242, 206, 249, 97, 21, 161, 224, 174, 93, 164, 155, 52, 26, 85, 173, 147, 50, 48, 245, 140, 177, 227, 29, 246, 226, 46, 130, 102, 202, 96, 192, 41, 35, 171, 13, 83, 78, 111, 213, 219, 55, 69, 222, 253, 142, 47, 3, 255, 106, 114, 109, 108, 91, 81, 141, 27, 175, 146, 187, 221, 188, 127, 17, 217, 92, 65, 31, 16, 90, 216, 10, 193, 49, 136, 165, 205, 123, 189, 45, 116, 208, 18, 184, 229, 180, 176, 137, 105, 151, 74, 12, 150, 119, 126, 101, 185, 241, 9, 197, 110, 198, 132, 24, 240, 125, 236, 58, 220, 77, 32, 121, 238, 95, 62, 215, 203, 57, 72], a = [462357, 472066609, 943670861, 1415275113, 1886879365, 2358483617, 2830087869, 3301692121, 3773296373, 4228057617, 404694573, 876298825, 1347903077, 1819507329, 2291111581, 2762715833, 3234320085, 3705924337, 4177462797, 337322537, 808926789, 1280531041, 1752135293, 2223739545, 2695343797, 3166948049, 3638552301, 4110090761, 269950501, 741554753, 1213159005, 1684763257];function s(t) {const n = [];for (let e = 0, r = t.length; e < r; e += 2)n.push(parseInt(t.substr(e, 2), 16));return n
}function c(t) {return t.map(t=>(t = t.toString(16),1 === t.length ? "0" + t : t)).join("")
}function u(t) {const n = [];for (let e = 0, r = t.length; e < r; e++) {const r = t.codePointAt(e);if (r <= 127)n.push(r);else if (r <= 2047)n.push(192 | r >>> 6),n.push(128 | 63 & r);else if (r <= 55295 || r >= 57344 && r <= 65535)n.push(224 | r >>> 12),n.push(128 | r >>> 6 & 63),n.push(128 | 63 & r);else {if (!(r >= 65536 && r <= 1114111))throw n.push(r),new Error("input is not supported");e++,n.push(240 | r >>> 18 & 28),n.push(128 | r >>> 12 & 63),n.push(128 | r >>> 6 & 63),n.push(128 | 63 & r)}}return n
}function g(t, n, r) {const i = new Array(4), o = new Array(4);for (let e = 0; e < 4; e++)o[0] = 255 & t[0 + 4 * e],o[1] = 255 & t[1 + 4 * e],o[2] = 255 & t[2 + 4 * e],o[3] = 255 & t[3 + 4 * e],i[e] = o[0] << 24 | o[1] << 16 | o[2] << 8 | o[3];i[0] ^= 2746333894,i[1] ^= 1453994832,i[2] ^= 1736282519,i[3] ^= 2993693404;for (let e, s = 0; s < 32; s += 4)e = i[1] ^ i[2] ^ i[3] ^ a[s + 0],n[s + 0] = i[0] ^= d(h(e)),e = i[2] ^ i[3] ^ i[0] ^ a[s + 1],n[s + 1] = i[1] ^= d(h(e)),e = i[3] ^ i[0] ^ i[1] ^ a[s + 2],n[s + 2] = i[2] ^= d(h(e)),e = i[0] ^ i[1] ^ i[2] ^ a[s + 3],n[s + 3] = i[3] ^= d(h(e));if (r === e)for (let e, a = 0; a < 16; a++)e = n[a],n[a] = n[31 - a],n[31 - a] = e
}function v(t, n, e) {const r = new Array(4), i = new Array(4);for (let o = 0; o < 4; o++)i[0] = 255 & t[4 * o],i[1] = 255 & t[4 * o + 1],i[2] = 255 & t[4 * o + 2],i[3] = 255 & t[4 * o + 3],r[o] = i[0] << 24 | i[1] << 16 | i[2] << 8 | i[3];for (let o, a = 0; a < 32; a += 4)o = r[1] ^ r[2] ^ r[3] ^ e[a + 0],r[0] ^= p(h(o)),o = r[2] ^ r[3] ^ r[0] ^ e[a + 1],r[1] ^= p(h(o)),o = r[3] ^ r[0] ^ r[1] ^ e[a + 2],r[2] ^= p(h(o)),o = r[0] ^ r[1] ^ r[2] ^ e[a + 3],r[3] ^= p(h(o));for (let o = 0; o < 16; o += 4)n[o] = r[3 - o / 4] >>> 24 & 255,n[o + 1] = r[3 - o / 4] >>> 16 & 255,n[o + 2] = r[3 - o / 4] >>> 8 & 255,n[o + 3] = 255 & r[3 - o / 4]
}function d(t) {return t ^ l(t, 13) ^ l(t, 23)
}function p(t) {return t ^ l(t, 2) ^ l(t, 10) ^ l(t, 18) ^ l(t, 24)
}function h(t) {return (255 & o[t >>> 24 & 255]) << 24 | (255 & o[t >>> 16 & 255]) << 16 | (255 & o[t >>> 8 & 255]) << 8 | 255 & o[255 & t]
}function l(t, n) {const e = 31 & n;return t << e | t >>> 32 - e
}function f(t) {const n = [];for (let e = 0, r = t.length; e < r; e++)t[e] >= 240 && t[e] <= 247 ? (n.push(String.fromCodePoint(((7 & t[e]) << 18) + ((63 & t[e + 1]) << 12) + ((63 & t[e + 2]) << 6) + (63 & t[e + 3]))),e += 3) : t[e] >= 224 && t[e] <= 239 ? (n.push(String.fromCodePoint(((15 & t[e]) << 12) + ((63 & t[e + 1]) << 6) + (63 & t[e + 2]))),e += 2) : t[e] >= 192 && t[e] <= 223 ? (n.push(String.fromCodePoint(((31 & t[e]) << 6) + (63 & t[e + 1]))),e++) : n.push(String.fromCodePoint(t[e]));return n.join("")
}function m(t, n, o, {padding: a="pkcs#7", mode: l, iv: h=[], output: p="string"}={}) {if ("cbc" === l && ("string" === typeof h && (h = s(h)),16 !== h.length))throw new Error("iv is invalid");if ("string" === typeof n && (n = s(n)),16 !== n.length)throw new Error("key is invalid");if (t = "string" === typeof t ? o !== e ? u(t) : s(t) : [...t],("pkcs#5" === a || "pkcs#7" === a) && o !== e) {const n = i - t.length % i;for (let e = 0; e < n; e++)t.push(n)}const d = new Array(r);g(n, d, o);const m = [];let b = h, y = t.length, _ = 0;while (y >= i) {const n = t.slice(_, _ + 16), r = new Array(16);if ("cbc" === l)for (let t = 0; t < i; t++)o !== e && (n[t] ^= b[t]);v(n, r, d);for (let t = 0; t < i; t++)"cbc" === l && o === e && (r[t] ^= b[t]),m[_ + t] = r[t];"cbc" === l && (b = o !== e ? r : n),y -= i,_ += i}if (("pkcs#5" === a || "pkcs#7" === a) && o === e) {const t = m.length, n = m[t - 1];for (let e = 1; e <= n; e++)if (m[t - e] !== n)throw new Error("padding is invalid");m.splice(t - n, n)}return "array" !== p ? o !== e ? c(m) : f(m) : m
}function jiami(t){var n = '30062AFC48C0E7B5B0918851C0445A37'var e1 = 0data = m(t, n, 1, e1)return data
}function jiemi(t){var n = '30062AFC48C0E7B5B0918851C0445A37'var e1 = undefineddata = m(t, n, 0, e1)return data
}

 仅作为笔记记录,如有问题请各位大佬来指导

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

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

相关文章

spark基本原理UI界面解读

这里是引用 1 八股文 1.1 基本原理 driver节点是整个应用程序的指挥所 指挥官是sparkcontext 环境&#xff1a;构建一个集群 应用程序提交 确定主节点&#xff0c;确定指挥所driver&#xff0c;确定指挥官sparkcontext sparkcontext会向资源管理器申请资源 会将作业分…

常见的几个Python技术难题

大家在日常开发中有没有遇到一些难题呢&#xff1f;计划后面出几期专题针对性的解决。大家如果有其它问题可以在评论区给出哈。 以下是几个Python技术难题的例子&#xff1a; 并发和多线程编程&#xff1a;Python的全局解释器锁&#xff08;GIL&#xff09;限制了多线程的并行…

华为OD机试 - 租车骑绿岛(Java JS Python C C++)

题目描述 部门组织绿岛骑行团建活动。租用公共双人自行车,每辆自行车最多坐两人,最大载重M。 给出部门每个人的体重,请问最多需要租用多少双人自行车。 输入描述 第一行两个数字m、n,分别代表自行车限重,部门总人数。 第二行,n个数字,代表每个人的体重,体重都小于…

CCF-CSP认证考试 202303-2 垦田计划 100分题解

更多 CSP 认证考试题目题解可以前往&#xff1a;CSP-CCF 认证考试真题题解 原题链接&#xff1a; 202303-2 垦田计划 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 问题描述 顿顿总共选中了 n n n 块区域准备开垦田地&#xff0c;由于各块区域大小不一&#xf…

Effective-C++阅读解析条款(条款一:视C++为一个语言联邦)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言 博主只是将书中内容用自己的理解写了出来&#xff0c;术语没有那么多&#xff0c;而且其中很多部分理解不是很透彻&#xff0c;对于C初学者来说&#xff0c;本专栏博客还是很有意义的&#xff0c;因为初学者看这本书通…

基于Java中的SSM框架实现快餐店线上点餐系统项目【项目源码+论文说明】

基于Java中的SSM框架实现快餐店线上点餐系统演示 摘要 随着计算机互联网的高速发展。餐饮业的发展也加入了电子商务团队。各种网上点餐系统纷纷涌现&#xff0c;不仅增加了商户的销售量和营业额&#xff0c;而且为买家提供了极大的方便&#xff0c;足不出户&#xff0c;就能订…

Vue双向数据绑定的简单实现-- Observer、Compiler、proxy

前言 双向数据绑定人人都会背了&#xff0c;已经没什么新奇了。 但是如果遇到XX喜欢问源码之类的&#xff0c;或者问你设计思路你又该如何应对呢&#xff0c;所以下面这篇文章主要是为了记录双向数据绑定的一个实现&#xff0c;采用了类的方式&#xff0c;积极向面向对象编程靠…

css实现自适应正方形

通过百分比&#xff08;%&#xff09;和宽高比通过vw或者vh通过百分比&#xff08;%&#xff09; padding-top 或者 padding-bottom以上列举三种方法&#xff0c;还有其他方法请各路大神评论区展示 展示 <style>* {margin: 0;padding: 0;}.box {width: 20%;aspect-rati…

软件测评中心:进行科技成果鉴定测试的注意事项和好处简析

软件产品科技成果鉴定是有效评价科技成果质量和水平的方法之一&#xff0c;也是鼓励科技成果通过市场竞争等方式得到有效的评价和认可&#xff0c;可以推动科技成果的进步和转化。 一、进行科技成果鉴定测试时的注意事项&#xff1a;   1、应由具备一定资质和能力的专业机构…

Android Studio实现内容丰富的安卓外卖平台

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 项目编号122 1.开发环境android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看公告 3.查看外卖分类 4.购物车&#xff0c; 5.个人中…

深度学习_微调_7

目标 微调的原理利用微调模型来完成图像的分类任务 微调的原理 微调&#xff08;Fine-tuning&#xff09;是一种在深度学习中广泛应用的技术&#xff0c;特别是在预训练模型&#xff08;Pretrained-Models&#xff09;的基础上进行定制化训练的过程。微调的基本原理和步骤如下…

AutoSAR配置与实践(深入篇)10.5 CANTP 层对意外到达的N-PDU处理策略

AutoSAR配置与实践(深入篇)10.5 CANTP 层对意外到达的N-PDU处理策略 CANTP 层对意外到达的N-PDU处理策略一、规范说明二、具体流程图解析2.1 发送端对意外到达的PDU的处理图解2.2 接收端对意外到达的PDU的处理图解CANTP 层对意外到达的N-PDU处理策略 ->返回总目录<- …

【项目】YOLOv5+PaddleOCR实现艺术字验证码识别

YOLOv5PaddleOCR实现艺术字类验证码识别 一、引言1.1 实现目标1.2 人手动点选验证码逻辑1.3 计算机点选逻辑 二、计算机验证方法2.1 PaddleOCR下方文字识别方法2.2 YOLOv5目标检测方法2.3 艺术字分类方法2.4 返回结果 三、代码获取 一、引言 1.1 实现目标 要识别的验证码类型…

c语言综合练习题

1.编写程序实现键盘输入一个学生的学分绩点 score&#xff08;合法的范围为:1.0—5.0&#xff09;&#xff0c;根据学生的学分绩点判定该学 生的奖学金的等级&#xff0c;判定规则如下表所示。 #include <stdio.h>int main() {float score;printf("请输入学生的学分…

Harbor-私有镜像仓库

目录 一、Harbor 原理说明 1.软件资源介绍 2.Harbor 特性 3.Harbor 认证过程 4.Harbor 认证流程 二、私有镜像仓库实验 1.环境准备 2.安装docker 3.配置镜像加速和私有仓库地址 4.搭建harbor仓库 5.本地windows浏览器访问配置 一、Harbor 原理说明 1.软件资源介绍 …

突破编程_C++_设计模式(访问者模式)

1 访问者模式的基本概念 C中的访问者模式是一种行为设计模式&#xff0c;它允许你在不修改类层次结构的情况下增加新的操作。这种模式将数据结构与数据操作解耦&#xff0c;使得操作可以独立于对象的类来定义。 访问者模式的主要组成部分包括&#xff1a; &#xff08;1&…

面试算法-62-盛最多水的容器

题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。…

CycleGAN训练及测试过程细节记录

CycleGAN训练及测试过程细节记录 文章目录 关于训练关于测试 关于训练 1、训练前将数据配置好&#xff0c;并在Pycharm中写好配置信息 2、关于训练过程的参数配置在 options/train_options.py options/base_options.py batch_size&#xff1a;批大小 crop_size&#xff1a;…

python实现--拓扑排序

拓扑排序是对有向无环图&#xff08;DAG&#xff09;进行排序的一种算法&#xff0c;它可以将图中的顶点排成一个线性序列&#xff0c;使得图中的任意一条有向边都从序列中的较早顶点指向较晚顶点。换句话说&#xff0c;如果图中存在一条从顶点A到顶点B的有向边&#xff0c;那么…

Android分区存储到底该怎么做

文章目录 一、Android存储结构二、什么是分区存储&#xff1f;三、私有目录和公有目录三、存储权限和分区存储有什么关系&#xff1f;四、我们应该该怎么做适配&#xff1f;4.1、利用File进行操作4.2、使用MediaStore操作数据库 一、Android存储结构 Android存储分为内部存储和…