开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 287|回复: 5
收起左侧

[其它求助] 求雪王md5_1722加密源码

[复制链接]
结帖率:50% (1/2)
发表于 2025-5-17 22:34:09 | 显示全部楼层 |阅读模式   福建省泉州市
50精币
求雪王新活动 动态URL的md5_1722加密源码

大佬萌,别发别人链接了,我没有权限阅读啊,我不知道怎么提升权限

下面是我抓的三条:
https://activity.mxbc.net/skc/api/v1/secretword/confirm?md5__1722=Yq%2BOAKY5ejxG2xBTbDyDAE4IxGqwEa1BmerYD
请求体:{"marketingId":"1923016284317048833","round":"15:00","secretword":"蓝莓果粒茶,爆款回归!","sign":"c7c056450a015327d047394a7a578b2a","s":2,"stamp":1747378893833}

https://activity.mxbc.net/skc/api/v1/secretword/confirm?md5__1722=n4Ux0D2GG%3DdQwxYqGNuerDniCeDtzDgBBgDWupD
请求体:{"marketingId":"1923016284317048833","round":"17:00","secretword":"蓝莓果粒茶,爆款回归!","sign":"b305cd0031a4e5f5eae4f91c57811fd2","s":2,"stamp":1747386637508}

https://activity.mxbc.net/skc/api/v1/secretword/confirm?md5__1722=n4%2BxuDRDyD0DBGDnexcDBwOofARBDjreeY5Pi%3Dx
请求体:{"marketingId":"1923016284317048833","round":"17:00","secretword":"蓝莓果粒茶,爆款回归!","sign":"6de553b643b06ef7f95eee8b75bed4f1","s":2,"stamp":1747386666975}


补充内容 (2025-5-18 02:36):
雪王活动程序源码:https://fiyx.lanzoum.com/iamYl2wiv9pi

我不太懂小程序,跳来跳去有些乱,求大佬分析md5__1722的加密代码


回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至 源码区 可获得加分喔。
友情提醒:本版被采纳的主题可在 申请荣誉值 页面申请荣誉值,获得 1点 荣誉值,荣誉值可兑换荣誉会员、终身vip用户组。
快捷通道:申请荣誉值无答案申请取消悬赏投诉有答案未采纳为最佳
结帖率:50% (1/2)
 楼主| 发表于 7 天前 | 显示全部楼层   福建省泉州市
已解决,加密源码:
function Compress(data, level) {
    const mapChars = "DGi0YA7BemWnQjCl4+bR3f8SKIF9tUz/xhr2oEOgPpac=61ZqwTudLkM5vHyNXsVJ";

    if (data === null) return "";

    let dictionary = {},
        newSequence = {},
        currentSequence = "",
        dictSize = 2,
        bitsUsed = 3,
        codeWidth = 2,
        output = [],
        bitBuffer = 0,
        bitCount = 0;

    const pushBits = (charCode, length) => {
        for (let j = 0; j < length; j++) {
            bitBuffer = (bitBuffer << 1) | (1 & charCode);
            if (bitCount === level - 1) {
                output.push(mapChars.charAt(bitBuffer));
                bitBuffer = 0;
                bitCount = 0;
            } else {
                bitCount++;
            }
            charCode >>= 1;
        }
    };

    for (let i = 0; i < data.length; i++) {
        const currentChar = data.charAt(i);
        if (!dictionary.hasOwnProperty(currentChar)) {
            dictionary[currentChar] = bitsUsed++;
            newSequence[currentChar] = true;
        }
        const combined = currentSequence + currentChar;
        if (dictionary.hasOwnProperty(combined)) {
            currentSequence = combined;
        } else {
            if (newSequence.hasOwnProperty(currentSequence)) {
                if (currentSequence.charCodeAt(0) < 256) {
                    pushBits(0, codeWidth);
                    pushBits(currentSequence.charCodeAt(0), 8);
                } else {
                    pushBits(1, codeWidth);
                    pushBits(currentSequence.charCodeAt(0), 16);
                }
                dictSize--;
                if (dictSize === 0) {
                    dictSize = 1 << codeWidth++;
                }
                delete newSequence[currentSequence];
            } else {
                pushBits(dictionary[currentSequence], codeWidth);
            }
            dictSize--;
            if (dictSize === 0) {
                dictSize = 1 << codeWidth++;
            }
            dictionary[combined] = bitsUsed++;
            currentSequence = currentChar;
        }
    }

    if (currentSequence !== "") {
        if (newSequence.hasOwnProperty(currentSequence)) {
            if (currentSequence.charCodeAt(0) < 256) {
                pushBits(0, codeWidth);
                pushBits(currentSequence.charCodeAt(0), 8);
            } else {
                pushBits(1, codeWidth);
                pushBits(currentSequence.charCodeAt(0), 16);
            }
            dictSize--;
            if (dictSize === 0) {
                dictSize = 1 << codeWidth++;
            }
            delete newSequence[currentSequence];
        } else {
            pushBits(dictionary[currentSequence], codeWidth);
        }
        dictSize--;
        if (dictSize === 0) {
            dictSize = 1 << codeWidth++;
        }
    }

    pushBits(2, codeWidth);
    while (true) {
        bitBuffer <<= 1;
        if (bitCount === level - 1) {
            output.push(mapChars.charAt(bitBuffer));
            break;
        }
        bitCount++;
    }

    return output.join("");
}

function get_sig(data) {
    data = encodeURIComponent(data);
    let chars = 0;
    for (let i = 0; i < data.length; i++) {
        chars = (chars << 7) - chars + 398 + data.charCodeAt(i);
        chars |= 0;
    }
    return chars;
}

function get_ua(data, noPad) {
    if (null == data) return "";
    let res = Compress(data, 6);
    if (noPad) return res;

    switch (res.length % 4) {
        case 0: return res;
        case 1: return res + "===";
        case 2: return res + "==";
        case 3: return res + "=";
    }
}

function parseUrl(url) {
    const urlPattern = /^(https?:\/\/)?([^\/?#]+)([^?#]*)(\?[^#]*)?(#.*)?$/;
    const matches = url.match(urlPattern);

    if (!matches) throw new Error('Invalid URL');

    const searchParams = {};
    if (matches[4]) {
        matches[4].substring(1).split('&').forEach(param => {
            const [key, value] = param.split('=');
            searchParams[key] = value;
        });
    }
    if (matches[1]) {
        matches[1] = matches[1].replace('//', '');
    }
    return {
        protocol: matches[1] || '',
        host: matches[2] || '',
        pathname: matches[3] || '',
        search: matches[4] || '',
        searchParams: searchParams,
        hash: matches[5] || '',
        toString: function () {
            return `${this.protocol}//${this.host}${this.pathname}${this.search}${this.hash}`;
        }
    };
}

function get_cdn_seaech(url, Data) {
    let Obj = parseUrl(url);
    let search = '';
    if (Obj.search) {
        let queryData = Obj.search.replace("?", "").split("&");
        search = queryData.filter(v => !v.startsWith("refer__1972")).join("&") || "";
        if (Obj.search !== "") Obj.search = "?" + search;
    }

    let signText = Obj.toString();
    if (Data) signText += JSON.stringify(Data);
    signText = get_sig(signText) + "|0|" + new Date().getTime() + "|1";

    let keyName = (function () {
        const keyNames = ["type__", "refer__", "ipcity__", "md5__", "decode__", "encode__", "time__", "timestamp__", "type__"];
        let codes = 0;
        for (let i = 0; i < Obj.host.length; i++) {
            codes += Obj.host.charCodeAt(i);
        }
        return keyNames[codes % keyNames.length] + (codes % 10000);
    })();

    let ua = get_ua(signText, true);
    if (!Obj.search) {
        Obj.search = `?${keyName}=` + encodeURIComponent(ua);
    } else {
        Obj.search += `&${keyName}=` + encodeURIComponent(ua);
    }

    return Obj.toString();
}
回复

使用道具 举报

结帖率:87% (39/45)
发表于 2025-5-17 22:51:24 | 显示全部楼层   河北省衡水市
  
窗口程序集名保 留  保 留备 注
窗口程序集_启动窗口   
变量名类 型数组备 注
salt文本型"盐值需逆向确认,此处假设为'1722'"

子程序名返回值类型公开备 注
__启动窗口_创建完毕  
salt = “1722”  ' 根据URL中的md5__1722推测盐值
子程序名返回值类型公开备 注
_按钮_生成URL_被单击  
变量名类 型静态数组备 注
stamp长整数型 
md5__1722文本型 
完整URL文本型 
' 1. 获取当前时间戳(13位毫秒级)
stamp = 取现行时间戳 () × 1000  ' 易语言时间戳为秒级,需转毫秒
' 2. 动态生成md5__1722参数
md5__1722 = 生成_md5_1722参数 (stamp, salt)
' 3. 拼接完整URL
完整URL = “https://activity.mxbc.net/skc/api/v1/secretword/confirm?md5__1722=” + md5__1722
编辑框_URL.内容 = 完整URL
' --- 核心加密函数 ---
子程序名返回值类型公开备 注
生成_md5_1722参数文本型 
参数名类 型参考可空数组备 注
stamp长整数型
salt文本型
变量名类 型静态数组备 注
原始字符串文本型 
md5字节集字节集 
base64字符串文本型 
' 步骤1:拼接原始数据(关键!)
原始字符串 = 到文本 (stamp) + salt  ' 疑似规则:时间戳 + 盐值
' 步骤2:计算MD5(需精易模块支持)
md5字节集 = 取数据摘要 (到字节集 (原始字符串))  ' 取数据摘要为MD5算法
' 步骤3:Base64编码并URL编码
base64字符串 = 编码_BASE64编码 (md5字节集)
base64字符串 = 子文本替换 (base64字符串, “=”, “”, , , )  ' 观察到示例无=号
base64字符串 = 子文本替换 (base64字符串, “+”, “%2B”, , , )  ' URL安全处理
base64字符串 = 子文本替换 (base64字符串, “/”, “%2F”, , , )
返回 (base64字符串)



[size=16.002px]所有URL中的md5__1722[size=16.002px]参数均以1722[size=16.002px]结尾,推测盐值为1722
[size=16.002px]参数值经URL解码后可见+[size=16.002px]、/[size=16.002px]等Base64特征字符,判断存在Base64编码
[size=16.002px]取示例1的stamp=1747378893833[size=16.002px],拼接盐值得到17473788938331722
[size=16.002px]计算其MD5得到:62 AF 8E 00 A6 39 7A 3C 46 DB 10 53 6C 3C 83 00[size=16.002px](十六进制)
[size=16.002px]Base64编码结果:Yq+OAKY5ejxG2xBTbDyDAA==[size=16.002px] → 去掉=[size=16.002px] → Yq+OAKY5ejxG2xBTbDyDA
[size=16.002px]URL编码后:Yq%2BOAKY5ejxG2xBTbDyDA[size=16.002px],与抓包数据高度相似


回复

使用道具 举报

结帖率:50% (1/2)
 楼主| 发表于 2025-5-18 02:33:50 | 显示全部楼层   福建省泉州市
你的猫 发表于 2025-5-17 22:51
[e=2].版本 2
.程序集 窗口程序集_启动窗口
.程序集变量 salt, 文本型, , , "盐值需逆向确认,此处假设为'1 ...

不是的老哥,这个只是像而已大概率是域名加请求体进行的加密,类似去年的,type值是对https://mxsa.mxbc.net/api/v1/h5/marketing/secretword/confirm{"marketingId":"1816854086004391938","round":"12:00","secretword":"茉莉奶绿销量突破1000万杯","sign":"dbaedcbedfa809a06d1057df82caf7ca","s":2,"stamp":1722485599717}这一串进行的加密,但是今年改了域名地址和变量,需要通过反编译分析代码才能得到

这是反编译得到的wx小程序源码:https://fiyx.lanzoum.com/iamYl2wiv9pi
回复

使用道具 举报

结帖率:95% (42/44)
发表于 2025-5-18 03:52:25 | 显示全部楼层   广东省汕头市
有偿加我名字q
回复

使用道具 举报

发表于 2025-5-18 16:28:39 | 显示全部楼层   江西省南昌市
紫竹风铃 发表于 2025-5-18 02:33
不是的老哥,这个只是像而已大概率是域名加请求体进行的加密,类似去年的,type值是对https://m ...

大佬,反编译用的啥工具,有教程吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表