微信APIv3签名算法 java版

官方文档,https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/qian-ming-sheng-cheng

注意点一:证书私钥获取,商户证书文件下载后,解压,如图,即可读到商户私钥,可以直接提取,也可以通过程序读取文件信息,官方地址:https://wechatpay-api.gitbook.io/wechatpay-api-v3/chang-jian-wen-ti/zheng-shu-xiang-guan#ru-he-cha-kan-zheng-shu-xu-lie-hao

注意点二:证书序列号,本人第一次用,获取方式:登陆商户平台【API安全】->【API证书】->【查看证书】,可查看商户API证书序列号。

java版代码

package com.wsw.sdk.utils;

import okhttp3.HttpUrl;
import sun.misc.BASE64Decoder;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Random;

/**
 * @ClassName WxAPIV3SignUtils
 * @Description: 微信API-V3签名工具
 * @Author wangshiwen
 * @Date 2020/3/30
 * @Version V1.0
 */
public class WxAPIV3SignUtils {
    // Authorization: <schema> <token>
    // GET - getToken("GET", httpurl, "")
    // POST - getToken("POST", httpurl, json)

    public static final String sign_type = "HMAC-SHA256";//签名类型,仅支持HMAC-SHA256。示例值:HMAC-SHA256
    private static final String schema = "WECHATPAY2-SHA256-RSA2048";
    private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private static final Random RANDOM = new SecureRandom();

    /**
     *
     * @param method
     * @param url
     * @param body
     * @param mchId 商户号
     * @param privateKey 商户证书私钥
     * @param serialNo 商户API证书序列号
     * @return
     * @throws Exception
     */
    public static String getToken(String method,HttpUrl url,String body,String mchId,String privateKey,String serialNo) throws Exception{
        String nonceStr = generateNonceStr();
        long timestamp = System.currentTimeMillis() / 1000;
        String message = buildMessage(method, url, timestamp, nonceStr, body);
        PrivateKey privateKey1 = getPrivateKey(privateKey);
        String signature = sign(message.getBytes("utf-8"),privateKey1);

        return schema + " " +"mchid=\"" + mchId + "\","
                + "nonce_str=\"" + nonceStr + "\","
                + "timestamp=\"" + timestamp + "\","
                + "serial_no=\"" + serialNo + "\","
                + "signature=\"" + signature + "\"";
    }

    /**
     *
     * @param message
     * @param privateKey 商户私钥
     * @return
     */
     private static String sign(byte[] message, PrivateKey privateKey) throws Exception{
         Signature sign = Signature.getInstance("SHA256withRSA");
         sign.initSign(privateKey);
         sign.update(message);

         return Base64.getEncoder().encodeToString(sign.sign());
    }

    private static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
        String canonicalUrl = url.encodedPath();
        if (url.encodedQuery() != null) {
            canonicalUrl += "?" + url.encodedQuery();
        }

        return method + "\n"
                + canonicalUrl + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + body + "\n";
    }

    /**
     * String转私钥PrivateKey
     * @param key
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }

}

调用示例:

Get请求

//请求方式:GET
        String url = "https://api.mch.weixin.qq.com/v3/payscore/user-service-state?service_id="+ param.getServiceId() +"&appid="+ param.getAppId() +"&openid=" + param.getOpenId();
        HttpUrl httpUrl = HttpUrl.parse(url);
      
        String token = WxAPIV3SignUtils.getToken("GET",httpUrl,"",param.getMchId(),param.getPrivateKey(),param.getSerialNo());

Post请求

//生成签名
            String url = "https://api.mch.weixin.qq.com/v3/payscore/serviceorder";
            HttpUrl httpUrl = HttpUrl.parse(url);
            String token = WxAPIV3SignUtils.getToken("POST",httpUrl,JSON.toJSONString(wxApplyPayScoreIn),payScoreConfig.getMchId(),payScoreConfig.getPrivateKey(),payScoreConfig.getSerialNo());
发布了4 篇原创文章 · 获赞 10 · 访问量 207

猜你喜欢

转载自blog.csdn.net/w1170384758/article/details/105393505