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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值