A brief introduction to the algorithm

The general procedure for signature generation is as follows: First step, set all the sent or received data as set M, and sort the non-empty parameter values in set M in alphabetical order according to the ASCII code of parameter names, using the FORMAT of URL key-value pairs (key1= ValuE1&key2 =value2...). Concatenated to the string stringA. Pay special attention to the following important rules: ◆ If the value of the parameter is empty, the signature is not involved. Parameter name is case-sensitive; ◆ When the verification call returns or the wechat active notification signature, the transmitted sign parameter does not participate in the signature, and the generated signature is verified with the sign value. The second step is to concatenate stringA with key to get stringSignTemp, perform MD5 operation on stringSignTemp, and convert all characters of stringSignTemp to uppercase. Get sign value signValue.Copy the code

Two, code implementation

public class WxPaySignUtils {

    public static final String MD5 = "MD5";
    public static final String HMAC_SHA256 = "HMAC-SHA256";

    /** * signature *@param data
     * @param key
     * @param signType
     * @return* /
    public static String sign(Map<String,String> data,String key,String signType){
        if(null == data || data.size() == 0 || null == key || key.trim().equals("") | |null== signType || ! (MD5.equals(signType) || HMAC_SHA256.equals(signType))){throw new RuntimeException("Parameter missing");
        }
        / / signature
        String signKey = "";
        SortedMap<String, String> sortedMap = new TreeMap<>(data);
        String paramStr = "";
        for (Map.Entry<String, String> stringStringEntry : sortedMap.entrySet()) {
            if(paramStr.equals("")){
                paramStr = stringStringEntry.getKey() + "=" + stringStringEntry.getValue();
            }else{
                paramStr = paramStr + "&" +stringStringEntry.getKey() + "=" + stringStringEntry.getValue();
            }
        }
        paramStr = paramStr + "&key=" + key;
        if(signType.equals(MD5)){
            signKey = getMD5(paramStr);
        }else{
            signKey = getHmacSha256(paramStr,key);
        }
        return signKey.toUpperCase();
    }

    /** * get MD5 *@param str
     * @return* /
    private static String getMD5(String str) {
        try {
            // Generate an MD5 encrypted calculation digest
            MessageDigest md = MessageDigest.getInstance("MD5");
            // Calculate the MD5 function
            md.update(str.getBytes());
            return byteArrayToHexString(md.digest());
        } catch (Exception e) {
            throw new RuntimeException("MD5 encryption error"); }}/** * Get HmacSha256 *@param message
     * @param key
     * @return* /
    private static String getHmacSha256(String message,String key){
        String outPut= null;
        try{
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(),"HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
            outPut = byteArrayToHexString(bytes);
        }catch (Exception e){
            throw new RuntimeException("HmacSHA256 encryption error");
        }
        return outPut;
    }

    /** * byte Array to hexadecimal string *@param b
     * @return* /
    private static String byteArrayToHexString(byte[] b) {
        StringBuilder sb = new StringBuilder();
        String stmp;
        for (int n = 0; b ! =null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                sb.append('0');
            sb.append(stmp);
        }
        returnsb.toString().toLowerCase(); }}Copy the code