欢迎来到Vincentyw的博客

该来的终究会来,该走的也一定会离开。凡事都存在前因后果,因缘成熟了,果报便产生了,无法阻挡。
但是发生过了就会消失,有来就有走,一切都是过客,把握自己当下的因缘,承担起自己该承担的责任,做好眼前该做的事情,做的时候尽全力,过去便放下,放下即自在。

获取微信签名方法调用

微信签名生成

1、微信签名生成

参照微信支付文档中心:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_0.shtml

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WxSendConfig {
    private static final Logger logger = LoggerFactory.getLogger(WxSendConfig.class);

    private static final Map<String,Object> wechatV3ApiParam = new HashMap<String,Object>();
    
      /**
     * 获取私钥。
     *
     * @param filename 私钥文件路径  (required)
     * @return 私钥对象
     */
    public static  PrivateKey getPrivateKey(String filename) throws IOException {

        String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
        try {
            String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");

            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(
                    new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }  
    
    /**
     * 获取证书。
     *
     * @param fis 证书文件流
     * @return X509证书
     */
    public static  X509Certificate getCertificate(InputStream fis) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(fis);
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(bis);
            cert.checkValidity();
            return cert;
        } catch (CertificateExpiredException e) {
            throw new RuntimeException("证书已过期", e);
        } catch (CertificateNotYetValidException e) {
            throw new RuntimeException("证书尚未生效", e);
        } catch (CertificateException e) {
            throw new RuntimeException("无效的证书文件", e);
        } finally {
            
            bis.close();
        }
    }
    
    /*组装签名串*/
    public static  String getToken(String method,String url,String body) throws Exception{
        String noncestr = UUID.randomUUID().toString().replace("-","");
        Long timestamp = System.currentTimeMillis()/1000;//精确到秒
        String message = buildMessage(method,url,body,timestamp,noncestr);
        String signature = getSign(message);
        String auth = "WECHATPAY2-SHA256-RSA2048 mchid=\""+wechatV3ApiParam.get("wechatMchId")+"\",nonce_str=\""+noncestr+"\",timestamp=\""+timestamp+"\",serial_no=\""+wechatV3ApiParam.get("serialNo")+"\",signature=\""+signature+"\"";
        logger.info("获得的Authorization:"+auth);
        return auth;
    }
    
    /**
     * V3  SHA256withRSA http请求签名.
     * @param method       请求方法  GET  POST PUT DELETE 等
     * @param canonicalUrl 请求地址
     * @param timestamp    当前时间戳   因为要配置到TOKEN 中所以 签名中的要跟TOKEN 保持一致
     * @param nonceStr     随机字符串  要和TOKEN中的保持一致
     * @param body         请求体 GET 为 "" POST 为JSON
     * @return the string
     * @throws Exception 
     */
    public static  String buildMessage(String method, String canonicalUrl, String body, long timestamp, String nonceStr) throws Exception {
        URL url = new URL(canonicalUrl);
        String signUrl = "";
        if ("GET".equals(method) && url.getQuery()!=null) {
            signUrl = url.getPath() + "?" + url.getQuery();
        }else{
            signUrl = url.getPath();
        }
        String messageStr = method + "\n"
                            + signUrl+ "\n"
                            + timestamp + "\n"
                            + nonceStr+ "\n"
                            + body+ "\n";
        logger.info("messageStr>>>\n"+messageStr);
        return messageStr;
    }
    
    /**
     * 获取签名
     * @param signatureStr 签名字符串
     * @return
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws SignatureException
     */
    public static  String getSign(String message) throws Exception{
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign((PrivateKey)wechatV3ApiParam.get("privateKey"));
        sign.update(message.getBytes("utf-8"));
        String signature = Base64.getEncoder().encodeToString(sign.sign());
        return signature;
    }

    public static Map<String, Object> getWechatv3apiparam() {
        return wechatV3ApiParam;
    }
    
    
    public static void main(String[] args) throws Exception {
        PrivateKey privateKey = getPrivateKey("/cert/apiclient_key.pem");
        System.out.println("key>>>"+privateKey);
        X509Certificate certificate = getCertificate(new FileInputStream("/cert/apiclient_cert.pem"));
        String serNo = certificate.getSerialNumber().toString(16);
        System.out.println("serNo>>>"+serNo);
        String noncestr = "c205f6726b1640a5a285cd999bceb5d4";
        Long timestamp = System.currentTimeMillis()/1000;//精确到秒
        String body = "{\"stock_id\":\"17822878\",\"out_request_no\":\"134348880120230804162600\",\"appid\":\"wx6d24a3a57853dde2\",\"stock_creator_mchid\":\"1343488801\"}";
        String message = buildMessage("POST","https://api.mch.weixin.qq.com/v3/marketing/favor/users/2323dfsdf342342/coupons",body,timestamp,noncestr);
        System.out.println("message>>>\n"+message);
         Signature sign = Signature.getInstance("SHA256withRSA");
         sign.initSign(privateKey);
         sign.update(message.getBytes("utf-8"));
         String signature = Base64.getEncoder().encodeToString(sign.sign());
         System.out.println("加密后得到signature>>>"+signature);
    }
}

 

posted on 2023-08-07 21:57  VincentYew  阅读(171)  评论(0编辑  收藏  举报

导航