首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >哦豁,我又成功逆向了一个sign

哦豁,我又成功逆向了一个sign

作者头像
偶尔敲代码
发布2026-03-17 11:25:33
发布2026-03-17 11:25:33
1000
举报
文章被收录于专栏:偶尔敲代码偶尔敲代码

大家在写脚本的时候,经常会遇到突然冒出个加密参数,然后就卡壳了。

有的人瞬间就不知所措就放弃了,有的人愿意多花费半小时,就成功逆向出来了。

前两天群友找我写个APP的脚本,一开始都还挺顺利,后面遇到了个签名参数 sign ,今天花了点时间给他折腾出来了,讲一下思路,很多简单加密都可以参考。

这是个POST请求,格式大致如下:

代码语言:javascript
复制
url = "https://****/api/sendIntegral" 
body = {
        "phone": phone,
        "integral": integral,
        "token": token,
        "sign": "982e876fc19b5d497376aa04a64cbe51cd4bd52ee0ab11919bf89b94c0a523aa"
    }

从上面可以看出 sign 是一串长度64个字符的字符串,首先猜它是SHA256加密。为啥这样猜?仅凭那丁点经验!

再凭借一点经验,sign 是几个参数用 & 拼接,再用SHA256加密得到的。我做了类似以下的尝试:

代码语言:javascript
复制
#随便排序
SHA256("phone=135***&integral=123&token=789")
#按参数名的字母顺序排序
SHA256("integral=123&phone=135***&token=789")

最终都得不到想要的结果,所以可能的原因有2个:一是加密算法不对;二是加密参数不对或顺序不对。

多次尝试后,我感觉是加密算法不对,应该是 HmacSHA256 ,这个和 SHA256 不是一个东西,最直观的区别是差个密钥,其他区别自行查阅:

对比维度

SHA256

HmacSHA256

密钥需求

无需密钥,仅依赖输入数据

必须提供密钥,密钥是计算的核心要素

主要用途

数据完整性校验(如文件校验、密码存储哈希)

消息认证(验证数据完整性 + 发送者身份)

安全性

仅能确保数据未被篡改,无法验证来源

既能确保数据未被篡改,又能验证来源合法性

输出唯一性

相同输入必产生相同输出

相同输入 + 相同密钥才产生相同输出

假设我的判断是对的,我现在就需要个密钥才能计算sign值,要这个密钥抓包是不可能抓得到的,所以只能去从源码中去捞相关信息,APP逆向我不会。凑巧,它有小程序,所以转战反编译小程序。

关于反编译小程序,查看这篇文章 👉 微信小程序解包

解包完成后,只有以下内容:

大致翻一翻,可以确认功能都在 app-service.js 里。为啥?因为它体积最大

打开这个js文件,直接搜索我们要的那个POST请求的关键词sendIntegral找到以下相关代码块:

代码语言:javascript
复制
zhuanjifen: function () {
var t = this;
this.$u.test.number(this.jisuanResult2) ? this.jisuanResult2 <= 0 ? this.$u.toast("转赠数量必须大于0") : e.showModal({
		title: "确认要向" + this.info1.phone + "转赠" + this.jisuanResult2 + "个积分吗?",
		success: function (n) {
if (n.confirm) {
				e.showLoading({
					title: "加载中...",
					mask: !0
				});
var o = {};
				o.token = e.getStorageSync("token"),
				o.phone = t.info1.phone,
				o.integral = t.jisuanResult2,
				o.descs1 = t.dimensionInfo.entName + ",消费" + t.moneyjisuan + "元,抵扣" + t.dimensionInfo.bili + "%," + t.info1.phone,
				o.descs2 = t.dimensionInfo.entName + ",消费" + t.moneyjisuan + "元,抵扣" + t.dimensionInfo.bili + "%," + t.userinfo.phone,
				o.money = t.moneyjisuan,
				o.dimensionNo = t.dimensionInfo.dimensionNo,
				o.bili = t.dimensionInfo.bili;
var i = {};
				i.token = e.getStorageSync("token"),
				i.integral = o.integral;
var a = (0, d.generateSign)(i, "yd9349");
				o.sign = a,
				t.$u.api.sendIntegral(o).then((function (n) {
						e.hideLoading(),
200 == n.code ? (t.getUserInfo(), e.showModal({
								title: n.msg,
								showCancel: !1
							})) : e.showModal({
							title: n.msg,
							showCancel: !1
						})
					}))
			}
                                        }
                                    }) : this.$u.toast("转赠数量格式有误,请输入本次消费金额")

注意上面代码块中的第20-24行。第24行定义了我们所需要的sign(o.sign)。它来自于变量a ,看起来是个奇葩的语法,但我们明显看到了个字符串"yd9349",它就是加密的密钥,所以这个加密算法是HmacSHA256。对于不懂js的我也实在看不懂,但没事,有AI! AI告诉我的答案:

代码语言:javascript
复制
1. 语法解析:(0, d.generateSign)(o, "yd9349")
外层括号 (0, d.generateSign):这是一个逗号表达式(comma operator),逗号表达式会按顺序执行多个操作,并返回最后一个操作的结果。这里 
0 是一个无意义的占位值,真正有效的是d.generateSign,因此整个表达式的结果等价于 d.generateSign(即获取到 d 对象中的 generateSign 函数)。
函数调用 
(o, "yd9349"):通过逗号表达式获取到函数后,直接以普通函数的形式调用,传入参数 o 和 "yd9349"。

2. 为什么要这样写?核心目的:统一 this 指向。****(后面我也不会,不看了哈哈)

3. 等价写法
这种写法等价于先将函数赋值给一个临时变量,再调用
var tempFunc = d.generateSign; // 剥离函数与原对象的关联
var s = tempFunc(o, "yd9349"); // 以普通函数形式调用,this 指向全局/undefined

从上面的答案我们知道了真正执行的函数是d.generateSign,参数为(i, "yd9349"),整理一下就是d.generateSign(i, "yd9349")。 参数i 很明显就是由token和integral组成的(21-23行)。

那现在就搜索generateSign,找到其函数定义:

代码语言:javascript
复制
generateSign: function (e, t) {
var a = Object.keys(e).sort().map((function (t) {
return "".concat(t, "=").concat(e[t])
			})).join("&");
return console.log("sortedParams", a),
	s.HmacSHA256(a, t).toString()
}

以上代码块第一行的参数e 即对应参数i,参数t 即对应密钥“yd9349”。代码段的功能是:

1. 排序键名:["integral", "token"](按字母顺序)。

2. 拼接参数:"integral=100&token=abc123"。

3.生成签名:通过 HmacSHA256 算法,用密钥"yd9349"对"integral=100&token=abc123"加密,得到最终签名字符串。

至此,sign 的加密算法就逆向完了,跑下脚本测试成功~

写在最后:

这是收了茶水费的脚本,APP和脚本就不方便分享了,主要提供一个思路,我觉得可以适用于很多简单的加密场景。这次比较简单不需要用到调试,直接框框一顿搜就可以了。有时候你觉得自己不会就不研究了,以后你再遇到依然不会。多研究多了解一点,都是在积攒经验。这也只是我众多逆向尝试中的一次成功经验,很多也是失败的。我没学过逆向,也没时间沉下心学,全靠每次多折腾那么半小时的,行就行,不行再说吧~

- End -

更多精彩文章

点击下方名片关注【偶尔敲代码】

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 偶尔敲代码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档