首页 > 其他分享 >获取微信签名方法调用

获取微信签名方法调用

时间:2023-08-07 22:14:58浏览次数:36  
标签:调用 java String 微信 cert 签名 new import security

微信签名生成

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);
    }
}

 

标签:调用,java,String,微信,cert,签名,new,import,security
From: https://www.cnblogs.com/vincentYw/p/17612851.html

相关文章

  • 微信小程序13 在请求url获取返回值后修改data变量的一个问题,es6箭头函数或外部定义变
    在之前解密电话时,我们有请求wx的apiwx.request({url:'https://api.weixin.qq.com/sns/jscode2session',data:{},success:(re)=>{//console.log('re:'+JSON.stringify(re));this.......
  • 微信小程序12 跳转,跳转时传参
    我们正常操作的话,肯定有很多页面之间的跳转,在微信小程序中navigator,跳转效果类似html中的a标签<navigatorurl="/pages/index/index">跳转到index</navigator>注意参数url指向要跳转的页面,本地跳转的话基本就是/pages/文件夹/文件名,没有后缀。这样点击标签后就会跳转......
  • 微信支付签名
    importcn.hutool.crypto.SecureUtil;importcom.dtyunxi.exchange.api.IFunctionAuthService;importorg.apache.commons.lang3.StringUtils;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.stereotype.Component;importjavax.......
  • 微信支付请求(带证书)
    importcn.hutool.core.lang.Pair;importcn.hutool.crypto.SecureUtil;importcom.dtyunxi.exchange.biz.model.ApiChannelType;importcom.dtyunxi.exchange.biz.utils.OkHttpUtil;importokhttp3.OkHttpClient;importorg.apache.http.HttpEntity;importorg.apache.......
  • Java Reflection机制 实现类的反射与动态调用
    JavaReflection机制实现类的反射与动态调用JavaReflection机制被广泛用于实现类的反射和动态调用,反射是指在运行时检查和操作类的能力。只需要一个类的名称或对象的引用,就可以获取类的信息,调用类的方法,创建对象实例等。JavaReflection机制实现类的反射与动态调用JavaRefle......
  • 微信小程序11 弹窗showToast,showLoading,showModal
    弹窗是相当常用的功能,在微信里用弹窗还是挺方便的。不同于我们写网页时,对于alert,confirm这些比较简陋的原生弹窗通常要引入第三方插件来美化,微信自带的弹窗效果还不错。放一个按钮,绑定showToast方法。<buttonbind:tap="showToast">点击弹窗1</button>Js方法通用showToast......
  • 微信公众号授权回调 vue网址中带#号的处理
    1、改变vue模式为history,小编没有试2、通过配置nginx实现   A、替换跳转网址中的#为其他字符串,例如我的    consturl=this._getUrl("https://open.weixin.qq.com/connect/oauth2/authorize",{appid:this.appId,......
  • 调用Geoserver发布的图层中文字段显示乱码
    通过OL使用WFS服务,调用发布的图层字段,中文字段显示为乱码  有几种原因:①指定打印的字符格式在代码中指定输出的编码格式,例如使用console.log('@@xxx',xzq.toString('utf-8'))来指定输出为UTF-8编码格式。②添加meta如果是在网页中输出乱码,可以在HTML的<head>标......
  • 微信开发之自动同意好友的技术实现
    简要描述:同意添加好友请求URL:http://域名地址/acceptUser请求方式:POST请求头Headers:Content-Type:application/jsonAuthorization:login接口返回参数:参数名必选类型说明wId是string登录实例标识v1是stringv1(从消息回调中取)v2是stringv2(从消......
  • Siemens 西门子SCL语言编程实例——循环调用电机
    导读西门子结构化编程可将不同的控制任务划分为不同的控制区域,相同控制功能数量众多的设备可利用具备多重背景的FB功能块重复调用来解决,使程序简洁、清晰、合理,易读性强,更改方便,为以后系统的升级改造提供了极大的便利。SCL语言的应用,更是大大减小了程序代码的占用空间,使西门......