微信商户转账到银行卡-java

本文详细介绍了在微信支付中遇到的公钥格式问题解决方案,推荐使用ssleye网站进行PKCS#1到PKCS#8的转换,避免公钥验证错误。同时,提供了RSA加密的代码实现,包括公钥加载、数据加密及工具类的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个注意写在最前面是因为微信获取公钥以后的格式问题推荐  http://www.ssleye.com/web/pkcs

 PKCS#1转成PKCS#8

不然会一直提示公钥不正确

 

------------------------------分割线----------------------------------------------------------

 

 

直接上代码,然后再看工具类

 @Before(Tx.class)
    public void index() throws Exception {

        Map<String, String> enter2card = new HashMap<>();
        //商户号
        enter2card.put("mch_id", Mchid);
        //商户订单号
        enter2card.put("partner_trade_no", getRandomStringByLength(32));
        //随机字符串
        enter2card.put("nonce_str", getRandomStringByLength(32));
        //收款方银行卡
        enter2card.put("enc_bank_no", toRSA("123654"));
        //收款方用户名
        enter2card.put("enc_true_name", toRSA("大王让我来巡山"));
        //收款开户行
        enter2card.put("bank_code", "1006");
        //付款金额
        enter2card.put("amount", "1");
        //付款说明
        enter2card.put("desc", "测试使用");
        String sign = PaymentKit.createSign(enter2card, Key);
        //签名
        enter2card.put("sign", sign);
        String result = payBank(enter2card, care, Mchid);
        System.out.println(result);
        Map<String, String> res = Xml2Map.xml2Map(result);
        System.out.println(res);
        log.debug(res.get("return_msg"));
        setAttr("res", res);
        setAttr("result", result);
        renderJson();

    }
  /*string使用rsa转换*/
    public String toRSA(String msg) throws Exception {
        PublicKey publicKey = RSAUtils.loadPublicKey(PUBLIC_PEM);
        String ms = RSAUtils.encrypt(msg.getBytes(), publicKey);
        return ms;
    }

    public void getPublicKry() {
        Map<String, String> enter2card = new HashMap<>();
        //商户号
        enter2card.put("mch_id", Mchid);
        //随机字符串
        enter2card.put("nonce_str", getRandomStringByLength(32));
        enter2card.put("sign_type", "MD5");
        String sign = PaymentKit.createSign(enter2card, Key);
        //签名
        enter2card.put("sign", sign);
        String result = EnterprisePayBankCard.getPublicKey(enter2card, care, "123654789");
        System.out.println(result);
        Map<String, String> params = Xml2Map.xml2Map(result);

        System.out.println(params);
        renderJson(Ret.create().set("rsult", result).set("params", params));
    }


    /**
     * 企业付款到银行
     *
     * @param params       请求参数
     * @param certPath     证书文件目录
     * @param certPassword 证书密码
     * @return {String}
     */
    public static String payBank(Map<String, String> params, String certPath, String certPassword) {
        return EnterprisePayBankCard.doPostSSL(PAY_BANK_URL, params, certPath, certPassword);
    }

    /**
     * 获取RSA加密公钥
     *
     * @param params       请求参数
     * @param certPath     证书文件目录
     * @param certPassword 证书密码
     * @return {String}
     */
    public static String getPublicKey(Map<String, String> params, String certPath, String certPassword) {
        return EnterprisePayBankCard.doPostSSL(GETPUBLICKEY_URL, params, certPath, certPassword);
    }


    public static String doPostSSL(String url, Map<String, String> params, String certPath, String certPass) {
        return HttpUtils.postSSL(url, PaymentKit.toXml(params), certPath, certPass);
    }

    //生成随机字符串
    public static String getRandomStringByLength(int length) {
        String base = "ABCDEFGHIJKLMNOPQRSTUrtdfhfjhh456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

 

 /*string使用rsa转换*/
    public String toRSA(String msg) throws Exception {
        PublicKey publicKey = RSAUtils.loadPublicKey(PUBLIC_PEM);
        String ms = RSAUtils.encrypt(msg.getBytes(), publicKey);
        return ms;
    }

    public void getPublicKry() {
        Map<String, String> enter2card = new HashMap<>();
        //商户号
        enter2card.put("mch_id", Mchid);
        //随机字符串
        enter2card.put("nonce_str", getRandomStringByLength(32));
        enter2card.put("sign_type", "MD5");
        String sign = PaymentKit.createSign(enter2card, Key);
        //签名
        enter2card.put("sign", sign);
        String result = EnterprisePayBankCard.getPublicKey(enter2card, care, "123654");
        System.out.println(result);
        Map<String, String> params = Xml2Map.xml2Map(result);

        System.out.println(params);
        renderJson(Ret.create().set("rsult", result).set("params", params));
    }


    /**
     * 根据订单号查询是都打到银行卡
     */
    public void checkOrBank() {
        Map<String, String> check = new HashMap<>();
        check.put("mch_id", Mchid);
        check.put("partner_trade_no", "123654");
        check.put("nonce_str", getRandomStringByLength(32));
        String sign = PaymentKit.createSign(check, Key);
        check.put("sign", sign);
        String result = doPostSSL(CHECK_OR_BANK, check, care, "123654");
        Map<String, String> res = Xml2Map.xml2Map(result);
        System.out.println(result);
        System.out.println(res);
        //购买通讯标识
        if("SUCCESS".equals(res.get("return_code"))){
            //返回信息,标识查询成功或者查询失败
           String return_msg=res.get("return_msg");
           //

        }else if("FAIL".equals(res.get("return_code"))){

        }


        renderJson(Ret.create().set("result", result).set("res", res));

    }

工具类

 

package com.tpxinxi.petsuu.mini.util;

import com.jfinal.kit.PathKit;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

/**
 * 描述:
 *
 * @author anliex
 *         2018/11/26 : 14:23.
 *         啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦
 */
public class RSAUtils {

    private static String RSA = "RSA";

    private final String pubKey = PathKit.getWebRootPath() + "/public.pem";

    private static final int KEYLENGTH = 2048;
    private static final int RESERVESIZE = 11;
    /**
     * 指定填充模式
     */
    private static final String CIPHERALGORITHM = "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING";


    /**
     * 用公钥加密 <br>
     * 每次加密的字节数,不能超过密钥的长度值减去11
     *
     * @param plainBytes 需加密数据的byte数据
     * @param publicKey  公钥
     * @return 加密后的byte型数据
     */
    public static String encrypt(byte[] plainBytes, PublicKey publicKey) throws Exception {
        int keyByteSize = KEYLENGTH / 8;
        int encryptBlockSize = keyByteSize - RESERVESIZE;
        int nBlock = plainBytes.length / encryptBlockSize;
        if ((plainBytes.length % encryptBlockSize) != 0) {
            nBlock += 1;
        }
        ByteArrayOutputStream outbuf = null;
        try {
            Cipher cipher = Cipher.getInstance(CIPHERALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);

            outbuf = new ByteArrayOutputStream(nBlock * keyByteSize);
            for (int offset = 0; offset < plainBytes.length; offset += encryptBlockSize) {
                int inputLen = plainBytes.length - offset;
                if (inputLen > encryptBlockSize) {
                    inputLen = encryptBlockSize;
                }
                byte[] encryptedBlock = cipher.doFinal(plainBytes, offset, inputLen);
                outbuf.write(encryptedBlock);
            }
            outbuf.flush();
            byte[] encryptedData = outbuf.toByteArray();
            return Base64.encodeBase64String(encryptedData);
        } catch (Exception e) {
            throw new Exception("ENCRYPT ERROR:", e);
        } finally {
            try {
                if (outbuf != null) {
                    outbuf.close();
                }
            } catch (Exception e) {
                throw new Exception("CLOSE ByteArrayOutputStream ERROR:", e);
            }
        }
    }


    /**
     * 从字符串中加载公钥
     *
     * @param publicKeyStr 公钥数据字符串
     * @throws Exception 加载公钥时产生的异常
     */
    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
        try {
            byte[] buffer = decodeBase64(publicKeyStr);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
            return keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("公钥非法");
        } catch (NullPointerException e) {
            throw new Exception("公钥数据为空");
        }
    }

    /***
     * decode by Base64
     */
    public static byte[] decodeBase64(String input) throws Exception {
        return Base64.decodeBase64(input);

    }

    /**
     * encodeBase64
     */
    public String encodeBase64(byte[] input) throws Exception {
        return Base64.encodeBase64String(input);
    }

    /**
     * 打印公钥信息
     *
     * @param publicKey
     */
    public void printPublicKeyInfo(PublicKey publicKey) {
        RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
//        log.info("----------RSAPublicKey----------");
//        log.info("Modulus.length=" + rsaPublicKey.getModulus().bitLength());
//        log.info("Modulus=" + rsaPublicKey.getModulus().toString());
//        log.info("PublicExponent.length=" + rsaPublicKey.getPublicExponent().bitLength());
//        log.info("PublicExponent=" + rsaPublicKey.getPublicExponent().toString());
    }

    public String encryptData(String data) throws Exception {
//        log.debug("pubKey================={}", pubKey);
        PublicKey publicKey = loadPublicKey(pubKey);
        return encrypt(data.getBytes("UTF-8"), publicKey);
    }


}

 

package com.tpxinxi.petsuu.mini.util;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述:
 *
 * @author anliex
 * @date 2018/11/26 11:26
 */
public class Xml2Map {
    /*xml转map*/
    public static Map<String, String> xml2Map(String xmlResult){
        Map<String, String> map = new HashMap<>();
        Document result ;
        try {
            result = DocumentHelper.parseText(xmlResult);
            // 获取根节点
            Element rootElt = result.getRootElement();
            //获取根节点下所有节点
            List<Element> list = rootElt.elements();
            //遍历节点
            for (Element element : list) {
                //节点的name为map的key,text为map的value
                map.put(element.getName(), element.getText());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }



}

 

结果奉上

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值