爬虫逆向sm3和sm4 加密 案例

news2025/2/24 6:21:12
注意!!!!某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
}

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

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

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

相关文章

C++利用开散列哈希表封装unordered_set,unordered_map

C利用开散列哈希表封装unordered_set,unordered_map 一.前言1.开散列的哈希表完整代码 二.模板参数1.HashNode的改造2.封装unordered_set和unordered_map的第一步1.unordered_set2.unordered_map 3.HashTable 三.string的哈希函数的模板特化四.迭代器类1.operator运算符重载1.动…

Vue2(七):脚手架、render函数、ref属性、props配置项、mixin(混入)、插件、scoped样式

一、脚手架结构&#xff08;Vue CLI&#xff09; ├── node_modules ├── public │ ├── favicon.ico: 页签图标 │ └── index.html: 主页面 ├── src │ ├── assets: 存放静态资源 │ │ └── logo.png │ │── component: 存放组件 │ │ …

未来已来?国内10家AI大模型盘点(附体验网址)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、阿里云——通义千问2、科大讯飞——星火大模…

Cookie使用

文章目录 一、Cookie基本使用1、发送Cookie2、获取Cookie 二、Cookie原理三、Cookie使用细节 一、Cookie基本使用 1、发送Cookie package com.itheima.web.cookie;import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.I…

嵌入式开发--获取STM32产品系列的信息

嵌入式开发–获取STM32产品系列和容量信息 获取STM32产品系列 有时候我们需要知道当前MCU是STM32的哪一个系列&#xff0c;这当然可以从外部丝印看出来&#xff0c;但是运行在内部的软件如何知道呢&#xff1f; ST为我们提供了一个接口&#xff0c;对于STM32的所有MCU&#x…

宏宇、萨米特、新明珠、金意陶、简一、科达、力泰、道氏、SITI BT、POPPI……35家参展商发布亮点

3月18日&#xff0c;2024佛山潭洲陶瓷展&#xff08;4月18-22日&#xff09;亮点发布会在广东新媒体产业园成功举办&#xff0c;主题为“我们不一样”。 陶城报社社长、佛山潭洲陶瓷展总经理李新良代表主办方&#xff0c;发布了2024佛山潭洲陶瓷展的“不一样”&#xff1b;佛山…

TikTok账号用什么IP代理比较好?

对于运营TikTok的从业者来说&#xff0c;IP的重要性自然不言而喻。 在其他条件都正常的情况下&#xff0c;拥有一个稳定&#xff0c;纯净的IP&#xff0c;你的视频起始播放量很可能比别人高出不少&#xff0c;而劣质的IP轻则会限流&#xff0c;重则会封号。那么&#xff0c;如何…

FPGA - SPI总线介绍以及通用接口模块设计

一&#xff0c;SPI总线 1&#xff0c;SPI总线概述 SPI&#xff0c;是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口。串行外设接口总线(SPI)&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的…

Day16:LeedCode 104.二叉树的最大深度 111.二叉树最小深度 222.完全二叉树的结点个数

104. 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 思路:根结点最大深度max(左子树最大深度,右子树最大深度)1 终止条件,结点为null,该结点最大深度为0 class Solution {publ…

【什么是Internet?网络边缘,网络核心,分组交换 vs 电路交换,接入网络和物理媒体】

文章目录 一、什么是Internet&#xff1f;1.从具体构成角度来看2.从服务角度来看 二、网络结构1.网络边缘1.网络边缘&#xff1a;采用网络设施的面向连接服务1.1.目标&#xff1a;在端系统之间传输数据1.2.TCP服务 2.网络边缘&#xff1a;采用网络设施的无连接服务2.1目标&…

MT管理器 使用手册

MT管理器 论坛&#xff1a;https://bbs.binmt.cc/ 使用技巧系列教程&#xff1a;https://www.52pojie.cn/thread-1259872-1-1.html MT管理器 使用手册 &#xff1a;https://mt2.cn/guide/&#xff1a;https://www.bookstack.cn/read/mt-manual/80b8084f6be128c0.md&#xff…

HC-SR501人体红外传感器

一、传感器介绍 二、代码 void infrared_Init(void) { GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);GPIO_InitStructure.GPIO_Pin GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN;GPIO_InitStructure.GPIO_OT…

jsp 3.21(3)jsp基本语法

一、实验目的 jsp标记、如指令标记&#xff0c;动作标记&#xff1b;变量和方法的声明&#xff1b;Java程序片&#xff1b;Java表达式&#xff1b; 二、实验项目内容&#xff08;实验题目&#xff09; 1、编写jsp文件&#xff0c;熟悉jsp动作标记include&#xff0c;参考课本上…

python之jsonpath的使用

文章目录 介绍安装语法语法规则举例说明 在 python 中使用获取所有结构所有子节点的作者获取所有子孙节点获取所有价格取出第三本书的所有信息取出价格大于70块的所有书本从mongodb 中取数据的示例 介绍 JSONPath能在复杂的JSON数据中 查找和提取所需的信息&#xff0c;它是一…

4.1 用源文件写汇编代码

汇编语言 1. 源程序 1.1 伪指令 汇编指令是有对应的机器码的指令&#xff0c;可以被编译为机器指令&#xff0c;最终为CPU所执行伪指令没有对应的机器指令&#xff0c;最终不被CPU所执行伪指令是由编译器来执行的指令&#xff0c;编译器根据伪指令来进行相关的编译工作 1.2…

【链表】Leetcode 19. 删除链表的倒数第 N 个结点【中等】

删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 解题思路 1、使用快慢指针找到要删除节点的前一个节点。2、删…

国际数字影像产业园:专注于数字影像领域的成都数字产业园

国际数字影像产业园&#xff08;数媒大厦&#xff09;&#xff0c;作为一个专注于数字影像产业的成都数字产业园&#xff0c;其服务优势体现在三大生态服务体系&#xff1a;公共服务、公务服务、产业服务。这三大服务体系不仅共享化、数字化、产业化&#xff0c;更致力于为企业…

带你玩透浮动float布局,详解(一)

文章目录 一 认识浮动二 浮动的规则浮动的规则一代码展示 浮动规则二代码展示 浮动规则四代码展示代码展示 浮动规则五 空隙的解决方案代码展示:第一种方式 放在一行第二种解决方式&#xff08;不推荐使用这种方式&#xff09;第三种方式采用浮动&#xff08;推荐&#xff0c;统…

用户中心项目(登录 + 用户管理功能后端)

文章目录 1.登录功能-后端1.思路分析2.完成对用户名和密码的校验1.com/sun/usercenter/service/UserService.java 添加方法2.com/sun/usercenter/service/impl/UserServiceImpl.java 添加方法3.com/sun/usercenter/service/impl/UserServiceImpl.java 新增属性 3.记录用户的登录…

SpringBoot如何写好单元测试

&#x1f413;序言 Spring中的单元测试非常方便&#xff0c;可以很方便地对Spring Bean进行测试&#xff0c;包括Controller、Service和Repository等Spring Bean进行测试&#xff0c;确保它们的功能正常&#xff0c;并且不会因为应用的其他变化而出现问题。 &#x1f413;单元测…