原改分代码为Python代码,

1
2
3
4
5
6
7
8
9
#!/usr/bin/python
# -*- coding: utf-8 -*-
print(“Hello World!”)
import requests
import json
import time
from Crypto.Cipher import AES
import base64

 

以上代码来自https://zhuanlan.zhihu.com/p/32473340 

考虑到很多同学没有Python环境,用起来并不是很方便,故参考此代码改写成Java版本。

GitHub链接:https://github.com/Seayon/Wxtyt_POST_DATA

另外简单写了个Web版提交工具,

http://java.zhaoxuyang.com/WxTyT/ (2018年1月3日 19:20,测试可用。)

但是不管哪种方法,都需要手动抓取微信跳一跳小游戏的session_id,抓包方法可以参考下面的或者自行搜索相关资料。

安卓抓包参考:安卓下使用Packet Capture抓取微信跳一跳小游戏的session_id值

iOS抓包参考:iOS下抓取微信跳一跳小游戏的session_id值

Java实现:

这里写了两个类,一个PKCS7加密的单独类,(参考自 WindCoder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
public class Pkcs7Encoder {
    // 算法名称
    static  final String KEY_ALGORITHM = “AES”;
    // 加解密算法/模式/填充方式
    static  final String algorithmStr = “AES/CBC/PKCS7Padding”;
    private static Key key;
    private static Cipher cipher;
    boolean isInited = false;
    //默认对称解密算法初始向量 iv
    static byte[] iv = { 0×30, 0×31, 0×30, 0×32, 0×30, 0×33, 0×30, 0×34, 0×30, 0×35, 0×30, 0×36, 0×30, 0×37, 0×30, 0×38 };
    public static void init(byte[] keyBytes) {
        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式
        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
        try {
            // 初始化cipher
            cipher = Cipher.getInstance(algorithmStr, “BC”);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * 加密方法
     *      –使用默认iv时
     * @param content
     *            要加密的字符串
     * @param keyBytes
     *            加密密钥
     * @return
     */
    public static byte[] encrypt(byte[] content, byte[] keyBytes) {
        byte[] encryptedText =  encryptOfDiyIV(content,keyBytes,iv);
        return encryptedText;
    }
    /**
     * 解密方法
     *      –使用默认iv时
     * @param encryptedData
     *            要解密的字符串
     * @param keyBytes
     *            解密密钥
     * @return
     */
    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
        byte[] encryptedText = decryptOfDiyIV(encryptedData,keyBytes,iv);
        return encryptedText;
    }
    /**
     * 加密方法
     *      —自定义对称解密算法初始向量 iv
     * @param content
     *              要加密的字符串
     * @param keyBytes
     *              加密密钥
     * @param ivs
     *         自定义对称解密算法初始向量 iv
     * @return 加密的结果
     */
    public static byte[] encryptOfDiyIV(byte[] content, byte[] keyBytes, byte[] ivs) {
        byte[] encryptedText = null;
        init(keyBytes);
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivs));
            encryptedText = cipher.doFinal(content);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptedText;
    }
    /**
     * 解密方法
     *
     * @param encryptedData
     *            要解密的字符串
     * @param keyBytes
     *            解密密钥
     * @param ivs
     *         自定义对称解密算法初始向量 iv
     * @return
     */
    public static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes,byte[] ivs) {
        byte[] encryptedText = null;
        init(keyBytes);
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs));
            encryptedText = cipher.doFinal(encryptedData);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptedText;
    }
}

执行请求的工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com;
import okhttp3.*;
import org.bouncycastle.util.encoders.Base64;
import org.json.JSONObject;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* @author: Seayon
* @date: 2017/12/31
* @time: 21:11
*/
public class Util {
    private static final MediaType JSON = MediaType.parse(“application/json;charset=utf-8″);
    private static final String WXGAME_URL = “https://mp.weixin.qq.com/wxagame/wxagame_settlement”;
    public static final String SESSIONID_ERROR = “SESSIONID有误,请检查”;
    private static String getActionData(String sessionKey, String encryptedData, String iv) {
        byte[] sessionKeyBy = sessionKey.getBytes();
        byte[] en = new byte[0];
        try {
            en = encryptedData.getBytes(“UTF-8″);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] ivBy = iv.getBytes();
        byte[] enc = Pkcs7Encoder.encryptOfDiyIV(en, sessionKeyBy, ivBy);
        return new String(Base64.toBase64String(enc));
    }
    public static String postData(String score, String times, String session_id) {
        String result = null;
        String content = “{\”score\”: ” + score + “, \”times\”: ” + times + “}”;
        String AES_KEY = null;
        try {
            AES_KEY = session_id.substring(0, 16);
        } catch (Exception e) {
            return SESSIONID_ERROR;
        }
        String AES_IV = AES_KEY;
        OkHttpClient okHttpClient = new OkHttpClient();
        String actionData = Util.getActionData(AES_KEY, content, AES_IV);
        String json = “{\”base_req\”:{\”session_id\”:\”" + session_id + “\”,\”fast\”:1},\”action_data\”:\”" + actionData + “\”}”;
        RequestBody requestBody = RequestBody.create(JSON, json);
        Request request = new Request.Builder()
                .url(WXGAME_URL)
                .header(“Accept”,”*/*”)
                .header(“Accept-Language”,”zh-cn”)
                .header(“User-Agent”,”Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304 MicroMessenger/6.6.1 NetType/WIFI Language/zh_CN”)
                .header(“Content-Length”,”680″)
                .header(“Content-Type”,”application/json”)
                .header(“Referer”,”https://servicewechat.com/wx7c8d593b2c3a7703/5/page-frame.html”)
                .header(“Host”,”mp.weixin.qq.com”)
                .header(“Connection”,”keep-alive”)
                .post(requestBody)
                .build();
        ResponseBody responseBody = null;
        try {
            responseBody = okHttpClient.newCall(request).execute().body();
            result = responseBody.string();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (responseBody != null) {
                responseBody.close();
            }
        }
        return result;
    }
}

执行测试

1
2
3
4
5
6
7
8
public class Main {
    public static void main(String[] args) {
        String sessionid = “==”;
        String score = “100″;
        String times = “700″;
        String result = Util.postData(score, times, sessionid);
        System.out.println(result);
    }

目前观察当执行errcode为0时代表成功,此时需要结束杀死微信的后台进程,重新进入微信,打开跳一跳小游戏,可以查看自己的分数,分数千万不要太高,我目前设置过的最高分是1024分,没有被封。

代码中使用到的依赖,Maven :

XHTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-debug-jdk15on</artifactId>
    <version>1.55</version>
</dependency>
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20171018</version>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.9.1</version>
</dependency>

 

https://zhaoxuyang.com/%E5%BE%AE%E4%BF%A1%E8%B7%B3%E4%B8%80%E8%B7%B3%E6%8A%93%E5%8C%85%E6%94%B9%E5%88%86-java%E5%AE%9E%E7%8E%B0/