这个注意写在最前面是因为微信获取公钥以后的格式问题推荐 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;
}
}