开发者

Java实现微信支付的签名算法示例

开发者 https://www.devze.com 2023-12-05 10:28 出处:网络 作者: Wen先森
目录签名算法第一步,设所有发送或者接收到的数据为集合M特别注意重要规则第二步,在stringA最后拼接上key得到stringSignTemp字符串签名算法
目录
  • 签名算法
    • 第一步,设所有发送或者接收到的数据为集合M
      • 特别注意重要规则
    • 第二步,在stringA最后拼接上key得到stringSignTemp字符串

    签名算法

    签名生成的通用步骤如下:

    第一步,设所有发送或者接收到的数据为集合M

    将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

    特别注意重要规则

    参数名ASCII码从小到大排序(字典序);

    如果参数的值为空不参与签名;

    参数名区分大小写;

    验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。

    微信接口可能增加字段,验证签名时必须支持增加的扩展字段

    第二步,在stringA最后拼接上key得到stringSignTemp字符串

    并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

    注意:密钥的长度为32个字节

    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.util.ObjectUtils;
    import Java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.*;
    /**
     * @author Wen先森
     * @version 1.0
     * @date 2022/8/25 11:07
     */
    @Slf4j
    public class SignatureUntils {
        public static final String  KEY="0de034fa56cf0ce676570d571de2705b";
        /**
         * 处理要签名的数据
         * 1. 获取参数content,content为json字符串
         * 2. 转换参数成URL 键值对的格式(即 key1=value1&key2=value2…)
         * 3. 返回整理好的待签名数据
         */
        private static String handleStr(Map<String,?> paramsMap){
            //转成map
            //获取参数名称转成List集合
            Set<String> keySet = paramsMap.keySet();
            List<String> paramNames = new ArrayList<String>(keySet);
            //对参数名称进行排序
            Collections.sort(paramNames);
            //把参数转化成url键值对格式并返回
            StringBuilder paramNameValue = new StringBuilder();
            for (String paramName : paramNames ) {
                if("sign".equals(paramName) || ObjectUtils.isEmpty(paramsMap.get(paramName))) {
                    continue;
                }else{
                    paramNameValue.append(paramName).append("=").append(paramsMap.get(paramName)).appenhttp://www.devze.comd("&");
                }
            }
           // paramNameValue.deleteCharAt(paramNameValue.length()-1);
            return paramNameValue.toString();
        }
        /**
         * android生成签名;
         *
         * @param params
         * @return
         */
        static public String signForInspiry(Map<String,?> params, String key) {
            //先排序
            String str = handleStr(params);
            StringBuffer sbkey = new StringBuffer(str);
            sbkey = sbkey.append("key=" + key);
            //MD5加密,结果转换为大写字符
            String sign = toMd5(sbkey.toString()).toUpperCase();
            return sign;
        }
        /**
         * 对字符串进行MD5加密
         *
         * @param str 需要加密的字符串
         * @return 小写MD5字符串 32位
         */
        public static String toMd5(String str) {
            String re = null;
            byte encrypt[];
            try {
                byte[] tem = str.getBytes();
                Mewww.devze.comssageDigest md5 = MessageDigest.getInstance("md5"android);
                md5.reset();
                md5.update(tem);
                encrypthttp://www.devze.com = md5.digest();
                StringBuilder sb = new StringBuilder();
                for (byte t : encrypt) {
                    String s = Integer.toHexString(t & 0xFF);
                    if (s.length() == 1) {
                        s = "0" + s;
                    }
                    sb.append(s);
                }
                re = sb.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return re;
        }
        public static boolean checkSign(String sign,Map<String,?> params,String key){
            try {
                String signValue = signForInspiry(params, key);
                if (StringUtils.endsWithIgnoreCase(signValue,sign)){
                    log.info("验签成功");
                    return true;
                }
            } catch (Exception e) {
                log.info("验签异常");
                e.printStackTrace();
            }
            log.info("验签失败");
            return false;
        }
        public static void main(String[] args) {
            String sign="81AA2B818EAD40FE2D8E7E3242C14577";
            String key="0de034fa56cf0ce676570d571de2705b";
            Map<String,Object> map = new HashMap<>();
            map.put("deviceSn","000SD50030180000001");
            map.put("timestamp","1661759090226");
            map.put("sign",sign);
            map.put("orderNo","HMP2208310000584428263559179");
            // 需要签名参数
            System.out.println("签名参数:"+map);
            String sortPram = handleStr(map);
            // 排序后和去掉sign参数之后
            System.out.println("排序后参数:"+sortPram);
            String signValue = signForInspiry(map, "0de034fa56cf0ce676570d571de2705b");
            // MD5加密并全部大写
            System.out.println("签名内容:"+signValue);
            // 验签
            checkSign(sign, map, key);
        }
    }

    以上就是Java实现微信支付的签名算法示例的详细内容,更多关于Java微信支付签名算法的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消