爬虫逆向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_hex

def sm4_jiami(t):
    result = ctx.call('jiami', t)
    return result

def 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&6

const 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 = 0
    data = m(t, n, 1, e1)
    return data
}

function jiemi(t){
    var n = '30062AFC48C0E7B5B0918851C0445A37'
    var e1 = undefined
    data = m(t, n, 0, e1)
    return data
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第39天 | 62.不同路径 , 63. 不同路径 II

动态规划章节理论基础&#xff1a; https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 62.不同路径 题目链接&#xff1a;https://leetcode.cn/problems/unique-paths/ 思路&#xff1a; 动规五部曲&#xff1a…

实战Python Socket编程:开发多用户聊天应用

实战Python Socket编程&#xff1a;开发多用户聊天应用 Python Socket 编程概述什么是Socket编程&#xff1f;Socket编程的应用场景Socket编程的重要性基本概念 环境准备Python版本必要的库开发环境配置调试工具 基本Socket编程创建Socket绑定Socket到端口监听连接接受连接发送…

基于C++的反射功能

需求&#xff1a; 利用C的发射机制&#xff0c;实现根据字符串创建实例对象。 代码&#xff1a; #ifndef OBJECT_H #define OBJECT_H#include <string> #include <map>typedef void* (*Constructor)();class CObjectFactory { public:static void registerClass…

Spring Boot轻松整合Minio实现文件上传下载功能【建议收藏】

一、Linux 安装Minio 安装 在/root/xxkfz/soft目录下面创建文件minio文件夹&#xff0c;进入minio文件夹&#xff0c;并创建data目录&#xff1b; [rootxxkfz soft]# mkdir minio [rootxxkfz soft]# cd minio [rootxxkfz minio]# mkdir data执行如下命令进行下载 [rootxxkf…

python基础——字符串的常见操作方法【下标索引,index,count,len,replace,split,strip】

&#x1f4dd;前言&#xff1a; 字符串是一种有序的&#xff0c;允许重复字符串存在的&#xff0c;不可修改的序列 这篇文章主要总结一下python中有关字符串的部分相关知识&#xff0c;以及字符串的常见操作方法&#xff1a; 1&#xff0c;和其他序列极其类似的操作方法 2&…

Three 材质纹理 (总结三)

THREE.MeshLambertMaterial&#xff08;网格 Lambert 材质&#xff09; 该材质使用基于非物理的Lambertian模型来计算反射率。可以用来创建暗淡的并不光亮的表面&#xff0c;该材质非常易用&#xff0c;而且会与场景中的光源产生反应。 MeshLambertMaterial属性 # .color : …

mysql中用逗号隔开的某字段,如何判断其他表的字段值是否在这个字段中

因为要增加需求&#xff0c;需要将线上表中老数据&#xff0c;修改为新数据的规则。 线上两张表&#xff0c;sequence_number中is_use有3作废、2到期状态&#xff0c;需要根据这个状态和school_ai_authorization中的is_deleted修改新增的state字段。 sequence_number表结构&…

数据分析实战-Python实现博客评论数据的情感分析

数据分析实战-Python实现博客评论数据的情感分析 学习建议SnowNLP基础什么是SnowNLP&#xff1f;SnowNLP情感分析 SnowNLP使用SnowNLP安装情感分析中文分词关键词提取拼音、词性标准 SnowNLP实战-博客评论数据的情感分析数据准备数据获取数据分析 总结 学习建议 现在很多网站、…

关于振弦采集仪的应用编写

instruction&#xff1a; 1、本应用基于深圳市安传物联科技有限公司所生产的八通道振弦变送器产品。该产品为MAX485 信号的变送设备&#xff0c; 并以Modbus协议输出。 2、本应用采用python语言编写。 功能实现&#xff1a; 1、发送&#xff1a; 01 03 10 00 00 02 C0 CB并…

JVM之调优(一)

背景&#xff1a;生产环境由于堆内存较大&#xff0c;fullgc 垃圾回收导致程序卡顿问题&#xff08;假死&#xff09; 目录 一、程序卡顿导致的影响 前端页面空白后端数据重复 二、解决方法 降低堆内存大小使用合适的垃圾回收器&#xff08;可以尝试&#xff0c;还未进行测试…

【python】爬取杭州市二手房销售数据做数据分析【附源码】

一、背景 在数据分析和市场调研中&#xff0c;获取房地产数据是至关重要的一环。本文介绍了如何利用 Python 中的 requests、lxml 库以及 pandas 库&#xff0c;结合 XPath 解析网页信息&#xff0c;实现对链家网二手房销售数据的爬取&#xff0c;并将数据导出为 Excel 文件的过…

捋顺【反函数求导】

设 d y d x f ( x ) 则 d x d y 1 f ( x ) 以 y t a n x 为 例 &#xff0c; d y / d x s e c 2 x , d x / d y 1 s e c 2 x c o s 2 x 到 此 为 止 &#xff0c; 似 乎 难 以 推 导 &#xff0c; 但 是 假 如 用 t a n x ( 也 就 是 y ) 将 c o s 2 x 表 示 出 来 &…

jenkins容器中安装python遇到问题

在Jenkins容器中安装配置Python时遇到问题 执行./configure --prefix/opt/python3/时遇到configure: error: no acceptable C compiler found in $PATH 这个问题就是缺少gcc编译环境。将gcc安装上即可&#xff1a; yum install -y gcc##前提是容器里的系统是cenos才可以&#…

实在智能Agent——RPA终极进化方向

RPA技术备受瞩目&#xff0c;它通过“机器人”自动化了人力执行的重复性、低复杂度任务&#xff0c;解放了员工并降低了企业成本。RPA机器人全天候运行&#xff0c;避免人为错误&#xff0c;高效处理任务&#xff0c;成为处理事务、操作数据、回应查询的理想选择。在管理后台&a…

易方达产品亏损仍存,“老鼠仓”阴影犹在,如何突出重围?

近日&#xff0c;易方达基金宣布易方达沪深300 ETF跻身“千亿规模ETF”行列&#xff0c;成为国内“ETF千亿俱乐部”的第三位成员。截至3月8日&#xff0c;该基金的规模增长112.21亿元&#xff0c;涨幅9.45%&#xff0c;规模增量在10亿以上的股票型ETF产品中排名第一。 回望202…

(网络安全)一款强大的逆向分析工具,开源!

工具介绍 Ghidra 是由美国国家安全局&#xff08;NSA&#xff09;研究部门开发的软件逆向工程&#xff08;SRE&#xff09;套件&#xff0c;用于支持网络安全任务。包括一套功能齐全的高端软件分析工具&#xff0c;使用户能够在各种平台(Windows、Mac OS和Linux)分析编译后的代…

TCP相关特性

协议段格式 • 源/⽬的端⼝号:表⽰数据是从哪个进程来,到哪个进程去; • 32位序号/32位确认号:后⾯详细讲; • 4位TCP报头⻓度:表⽰该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最⼤⻓度是15*460 • 6位标志位: ◦ URG:紧急指针是否有效 ◦ ACK:确认号是否有效…

排序(10)——非比较排序计数排序

目录 思想 局限性 基本思路 代码实现 特性总结 思想 思想&#xff1a;计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。 操作步骤&#xff1a; 统计相同元素出现次数根据统计的结果将序列回收到原来的序列中 首先有一个a数组&#xff0c;里面都有元素&a…

部署prometheus+Grafana可视化仪表盘监控服务

一、部署prometheus及监控仪表盘 简介 Prometheus是开源监控报警系统和时序列数据库(TSDB)。 Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态&#xff0c;任意组件只要提供对应的HTTP接口就可以接入监控&#xff0c;输出被监控组件信息的HTTP接口被叫做expo…