package com.nova.sankuai.infra.utils.huifubao.api; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.nova.sankuai.infra.utils.huifubao.common.HttpUtil; import com.nova.sankuai.infra.utils.huifubao.common.SignEncrypt; import com.nova.sankuai.infra.utils.huifubao.common.Utils; import com.nova.sankuai.infra.utils.huifubao.request.BaseRequest; import com.nova.sankuai.infra.utils.huifubao.respone.BaseResponse; import com.nova.sankuai.infra.utils.huifubao.respone.QuerySignRespone; import com.nova.sankuai.infra.utils.huifubao.respone.SignResponse; import lombok.Data; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; @Data public abstract class AbstractHeepayClient implements HeepayClient { private String serverUrl; private String method; private String version; private String merchantId; private X509Certificate cert; private PrivateKey privateKey; private PublicKey heepayPublicKey; public AbstractHeepayClient(String serverUrl, String privateKeystr, String publicKeystr, String method, String version, String merchantId) throws Exception { this.serverUrl = serverUrl; KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] privateKeyPath = org.bouncycastle.util.encoders.Base64.decode(privateKeystr.getBytes()); byte[] publicKeyPath = org.bouncycastle.util.encoders.Base64.decode(publicKeystr.getBytes()); privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec((privateKeyPath))); heepayPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyPath)); this.method = method; this.version = version; this.merchantId = merchantId; } public SignResponse submitSign(BaseRequest baseRequest) { BaseResponse response = doPost(baseRequest, true); SignResponse signResponse = new SignResponse(); if (response.getData() != null) { signResponse = JSON.parseObject(response.getData(), SignResponse.class); } signResponse.setCode(response.getCode()); signResponse.setMsg(response.getMsg()); signResponse.setSub_code(response.getSub_code()); signResponse.setSub_msg(response.getSub_msg()); signResponse.setData(response.getData()); signResponse.setSign(response.getSign()); return signResponse; } public QuerySignRespone querySign(BaseRequest baseRequest) { BaseResponse response = doPost(baseRequest, false); QuerySignRespone querySignRespone = new QuerySignRespone(); if (response.getData() != null) { querySignRespone = JSON.parseObject(response.getData(), QuerySignRespone.class); } querySignRespone.setCode(response.getCode()); querySignRespone.setMsg(response.getMsg()); querySignRespone.setSub_code(response.getSub_code()); querySignRespone.setSub_msg(response.getSub_msg()); querySignRespone.setData(response.getData()); querySignRespone.setSign(response.getSign()); return querySignRespone; } private BaseResponse doPost(BaseRequest baseRequest, boolean flag) { SignEncrypt signEncrypt = new SignEncrypt(); HttpUtil httpUtil = new HttpUtil(); BaseResponse baseResponse = new BaseResponse(); try { baseRequest.setMerch_id(merchantId); baseRequest.setVersion(version); baseRequest.setMethod(method); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); baseRequest.setTimestamp(df.format(new Date())); Map map = Utils.convertBeanNoneEmpty(baseRequest); String bizJson = Utils.coverMap2String(map); //签名 String sign = signEncrypt.sign(bizJson, privateKey); baseRequest.setSign(sign); //bizContent加密 String content = signEncrypt.encrypt(baseRequest.getBiz_content(), heepayPublicKey); baseRequest.setBiz_content(content); System.out.println("加密后------------------------------------------------------------------------>" + content); System.out.println(); System.out.println("待签名------------------------------------------------------------------------>" + bizJson); System.out.println(); System.out.println("签名后------------------------------------------------------------------------>" + sign); System.out.println(); String res = httpUtil.sendJsonHttpPost(serverUrl, JSON.toJSONString(baseRequest)); System.out.println("resq------------------------------------------------------------------------>" + JSON.toJSONString(baseRequest)); System.out.println(); System.out.println("resp------------------------------------------------------------------------>" + res); System.out.println(); //解析response 取到data并解密 ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(res.toString()); String data = jsonNode.get("data").asText(); //decrypt为解密后的值 String decrypt = signEncrypt.decrypt(data, privateKey); //继续解析解密后的值拿到sign_url JsonNode jsonNode1 = objectMapper.readTree(decrypt.toString()); String sign_url = jsonNode1.get("sign_url").asText(); System.out.println("sign_url------------------------------------------------------------------------>" + sign_url); Map resMap = Utils.convertBeanNoneEmpty(baseResponse); String resJson = Utils.coverMap2String(resMap); if (baseResponse.getSign() != null) { boolean result = signEncrypt.verify(resJson, baseResponse.getSign(), heepayPublicKey); System.out.print(result); if (result) { return baseResponse; } else { baseResponse.setCode("40002"); baseResponse.setMsg("返回结果验签异常"); } } } catch (Exception e) { baseResponse.setCode("40004"); baseResponse.setMsg("发送请求异常"); } return baseResponse; } }