鉴于目前很多app 都加壳 逆向的话 需要脱壳 脱壳反编译之后 还会遇到各种反调试的情况 难度不小 不如换个渠道 从小程序入手 其实是个不错的选择 - -

一.抓包分析

java实现微信小程序支付签名计算_爬虫


可以发现 在post请求的参数里面 有个sign

其他的都是些设备信息,指纹信息 应该是固定的 可以不管

还有就是些 页数 时间戳等数据,,要解的就是这个sign了

二、调试

将小程序解包 反编译之后

打开微信开发者工具 搜索看看

先搜索关键字sign 看看

java实现微信小程序支付签名计算_3c_02


可以发现 结果有很多 我们懒得去找了 直接换个参数搜吧

再试着搜索下timestamp

java实现微信小程序支付签名计算_3c_03


嘿嘿 结果不多 一下就找到了(nice)

直接打上断点 看看

java实现微信小程序支付签名计算_python_04


生成sign的参数 是一个object对象 里面包含了一些信息 包括页数 设备信息 时间戳等等

可以发现 就是和 post 请求的参数是一模一样的 只不过这里需要计算一下这个sign值了

ok

接着看看这个o函数

o = function(e) {
            for (var t = c(e), i = "", s = 0; s < t.length; s++) i += t[s][0] + "" + t[s][1];
            return (0, r.default)(n.appSecret + i + n.appSecret).toLowerCase();
        }

这个函数并不复杂 只不过里面嵌套了一个c函数
再看看这个c函数

c = function(e) {
            var t, i = [];
            for (t in e) i.push([ t, e[t] ]);
            return d(i, function(e, t) {
                return e[0] > t[0];
            }), i;
        }

然后c函数里面又嵌套了d函数

d = function(e, t) {
            for (var i = 0; i < e.length - 1; i++) {
                for (var r, s = !0, n = 0; n < e.length - 1 - i; n++) 0 < t(e[n], e[n + 1]) && (r = e[n], 
                e[n] = e[n + 1], e[n + 1] = r, s = !1);
                if (s) return !1;
            }
        };

可以先不管这些函数做了什么 我们直接打断点到下一步

java实现微信小程序支付签名计算_java实现微信小程序支付签名计算_05


可以 发现 这里是把 对象的key和value拼接起来了

然后这里还有个n.appSecret

看看是什么

java实现微信小程序支付签名计算_爬虫_06


是个这东西 既然名字都叫secret 那肯定是个固定字符串了

好到这里 可以发现

n.appSecret + i + n.appSecret

把上面对象转化的字符串 的前后都 拼接上这个 固定字符串 然后丢给函数加密

java实现微信小程序支付签名计算_python_07


看看这个加密函数把

function v(e, t, i) {
            return t ? i ? f(t, e) : g(f(t, e)) : i ? h(e) : g(h(e));
        }

这就是 加密的函数 可以先现 有点绕哈 不急 我们知道这个加密只传了一个参数

那么这里的实参 t,i都是undefined 也就是说

这个函数的也就等于 return g(h(e)); 就是这里的这个 g(h(e))

java实现微信小程序支付签名计算_字符串_08


就是这个没错了

继续吧

function h(e) {
            return l(d(u(e = p(e)), 8 * e.length));
        }

然后这里这个h又嵌套了4个函数 我滴个天

好了 接下来经过我一下午的折腾扣代码 其实发现 是个md5值(妙啊)

看起来很简单 结果我扣了一下午的代码 后面发现里面是一个很大的递归 导致 nodejs执行报错

后来灵光一闪 发现 是个md5值

大快人心啊

java实现微信小程序支付签名计算_3c_09


其实到这里的时候早就应该想到是md5了

但奈何 它的js代码里面没有出现 任何md5,encrypt等相关的关键字

导致我 以为是它独特的签名计算方式 才浪费了很多时间去扣代码。焯

所以 思路和经验很重要!!

三,代码还原

既然已经知道它的签名生成逻辑

试试看 先把js扣出来

d = function(e, t) {
            for (var i = 0; i < e.length - 1; i++) {
                for (var r, s = !0, n = 0; n < e.length - 1 - i; n++) 0 < t(e[n], e[n + 1]) && (r = e[n],
                e[n] = e[n + 1], e[n + 1] = r, s = !1);
                if (s) return !1;
            }
        }

c = function(e) {
            var t, i = [];
            for (t in e) i.push([ t, e[t] ]);
            return d(i, function(e, t) {
                return e[0] > t[0];
            }), i;
        }
function o(e) {
            for (var t = c(e), i = "", s = 0; s < t.length; s++) i += t[s][0] + "" + t[s][1];
            return "15cdf1eaf2110a3009bf2be5d3e53c3c" + i + "15cdf1eaf2110a3009bf2be5d3e53c3c"
        }

再用py看看

java实现微信小程序支付签名计算_3c_10

200 OK!