Spring Boot Wechat-Verify Server Effectiveness

Posted by phelpsa on Sun, 14 Jul 2019 22:39:40 +0200

Summary

To access the development of Wechat Public Platform, developers need to follow the following steps:

  1. Develop validity logic to validate the address of Wechat Verification Server on its own server
  2. Fill in the address information of your own server on the Wechat platform
  3. On its own server, it implements business logic according to Wechat interface document

Step 1: Implement validity logic to verify server addresses

After the developer submits the information, the Wechat server will send the GET request to the server address URL filled in. The GET request carries four parameters:

parameter describe
signature Wechat encryption signature, signature combines the token parameter filled by the developer and the timestamp parameter and nonce parameter in the request.
timestamp time stamp
nonce random number
echostr Random string

Developers validate requests by validating signature s (validation is provided below).

If the GET request is confirmed to be from the Wechat server, please return the echostr parameter content as it is, the access will take effect and become a successful developer, otherwise the access will fail.

The encryption/verification process is as follows:

  1. Lexicographic ordering of three parameters: token, timestamp and nonce
  2. sha1 encryption by splicing three parameter strings into one string
  3. The encrypted string obtained by the developer can be compared with signature to indicate that the request originated from Wechat.

java code:

package com.jeiker.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

@RestController
@RequestMapping("/wechat")
public class WeChatController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    // URL:   http://www.xxxx.com/wechat/
    // Token: Here TOKEN is the Token that configures the information for the Wechat interface.

    private String TOKEN = "wechat";

    /**
     * Verify the validity of the server address of the Wechat background configuration
     *
     * Receive and verify four request parameters
     *
     * @param signature Wechat Encrypted Signature
     * @param timestamp time stamp
     * @param nonce     random number
     * @param echostr   Random string
     * @return echostr
     */
    @GetMapping("/")
    public String checkName(@RequestParam(name = "signature") String signature,
                            @RequestParam(name = "timestamp") String timestamp,
                            @RequestParam(name = "nonce") String nonce,
                            @RequestParam(name = "echostr") String echostr) {

        logger.info("WeChat-Start checking signatures");
        logger.info("Received from Wechat echostr Character string:{}", echostr);

//        The encryption/verification process is as follows:
//        1. Lexicographic ordering of three parameters: token, timestamp and non CE
//        2. sha1 encryption by splicing three parameter strings into one string
//        3. The encrypted strings obtained by the developer can be compared with signature s to identify that the request originated from Wechat.

        // 1. Sorting
        String sortString = sort(TOKEN, timestamp, nonce);
        // 2.sha1 Encryption
        String myString = sha1(sortString);
        // 3. String Check
        if (myString != null && myString != "" && myString.equals(signature)) {
            logger.info("WeChat-Signature verification passed");
            //If the verification is successfully returned to echostr as it is, the Wechat server will receive the output before confirming the completion of the verification.
            logger.info("Responding to Wechat echostr Character string:{}", echostr);
            return echostr;
        } else {
            logger.error("WeChat-Signature verification failed");
            return "";
        }
    }

    /**
     * Sorting method
     * @param token     Token
     * @param timestamp time stamp
     * @param nonce     random number
     * @return
     */
    public String sort(String token, String timestamp, String nonce) {
        String[] strArray = {token, timestamp, nonce};
        Arrays.sort(strArray);
        StringBuilder sb = new StringBuilder();
        for (String str : strArray) {
            sb.append(str);
        }

        return sb.toString();
    }

    /**
     * sha1 Encryption of Strings
     *
     * @param str String to be encrypted
     * @return    Encrypted content
     */
    public String sha1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create a hexadecimal string
            StringBuffer hexString = new StringBuffer();
            // Converting byte arrays to hexadecimal numbers
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}

Step 2: Fill in the server configuration on Wechat Public Number Platform

After login to the official website of Weixin Public Platform, click the "Modify Configuration" button on the background management page of Weixin Public Platform, and fill in the server address (URL), Token and Encoding AESKey, where the URL is the interface URL used by developers to receive Weixin messages and events. Token can be filled in arbitrarily by developers to generate signatures (the Token will be compared with Token included in the interface URL to verify security). Encoding AESKey is manually filled in or randomly generated by the developer and will be used as a message body encryption and decryption key.

After filling in the information, click the "Submit" button (take the test platform as an example):

Wechat will send a GET validation request to the completed URL, at which time the back end will receive the request output log:

After echostr verification, the original version is returned to the Wechat server, and the verification of the server address is completed.

Server log output:

Wechat - Start Checking Signatures
 Received echostr string from Wechat: 4868431563403787247
 Wechat-Signature Verification Passed
 echostr string replying to wechat: 4868431563403787247

Step 3: Implementing business logic based on interface documents

After verifying the validity of the URL, the access will take effect and become a developer.

If the public number type is service number (subscription number can only use ordinary message interface), it can apply for authentication in the public platform website, and the successful authentication service number will obtain many interface privileges to meet the needs of developers.

Topics: SHA1 Java encoding