调用招商银行接口(手把手教程,附调用接口工具类) 您所在的位置:网站首页 招商随行是什么 调用招商银行接口(手把手教程,附调用接口工具类)

调用招商银行接口(手把手教程,附调用接口工具类)

2024-01-19 14:27| 来源: 网络整理| 查看: 265

手把手教你调用招商银行接口 一、下载示例代码二、申请测试环境、或者生产环境加入到示例代码三、调用招商银行接口参数拼装四、调用接口测试五、最后,贴上我自己改造过的工具类1、这是获取银行环境参数的工具类2、新增记账子单元 NTDMAADD-参数dto3、这是调用银行接口的工具类,一般就用“commonRequestMethod”方法4、工具类CMBBase64

一、下载示例代码

首先到招商银行的文档中心下载示例代码: https://openbiz.cmbchina.com/developer/UI/Business/CloudDirectConnect/Public/DocumentCenter/DocDetail.aspx?bizkey=DCCT20201215143758097&fabizkey=1&treeID=100034594

在这里插入图片描述 在这里插入图片描述 这个下载下来是一个压缩包,打开压缩包,里面有一个,java文件这个文件就是示例代码了。

二、申请测试环境、或者生产环境加入到示例代码

在这里插入图片描述 这里面的公钥、私钥等环境参数是不能直接用的(红框框住的那些就是),需要企业事先跟招商银行申请测试环境,申请成功后将申请环境中的参数与示例代码的参数一一替换。

三、调用招商银行接口参数拼装

在这里插入图片描述 这个data参数里面的就是招商银行的接口参数,这样看有点费劲,格式一下json 在这里插入图片描述

注意,reqid是有格式要求的

在这里插入图片描述

这个接口的funcode是“NTDMAADD”,在文档中找到对应的接口详情 在这里插入图片描述 会有接口的使用说明,请求和响应的参数介绍,往下拉还会有调用示例和响应示例 在这里插入图片描述

四、调用接口测试

在调用接口前记得找管理网银的同事添加一下本机ip的白名单,否则会出现白名单错误,出现这个错误说明接口传参没问题了,就差白名单了。 在这里插入图片描述 添加了白名单之后,如果响应体中参数“resultcode”的值为“SUC0000”,说明接口调用成功,保存下需要的返回信息即可。

当然也可以用postman测试 在这里插入图片描述 但是“DATA”参数还是需要用示例代码中的方法加密,个人觉得意义不大。

五、最后,贴上我自己改造过的工具类

这个不是调用接口必要的,只是觉得经过我改动后调用接口方便一点

1、这是获取银行环境参数的工具类 import lombok.Data; /** * 银行配置dto * * @author:user * @date: 2022-03-25 10:51 */ @Data public class BankConfigDto { //公钥 private String pubkeyStr; //私钥 private String prikeyStr; //AESKEY private String AESKEY; //用户id private String UID; //访问地址 private String URL; //=============以下参数并不是所有的银行接口都需要,所以是非必填的 //付方账号 private String payacc; //模式编号 private String busmod; //网银审批标志 可选;Y 直连经办,客户端审批 private String grtflg; //分行号 private String bbknbr; } 2、新增记账子单元 NTDMAADD-参数dto

这只是这个接口的dto,后面要调用其他接口再增加对应的参数dto。

import lombok.Data; /** * 新增记账子单元 NTDMAADD-参数dto * * @author:user * @date: 2022-03-25 18:14 */ @Data public class NTDMAADDParam { //账号 private String accnbr; //记账子单元编号 // 不超过 10 位 private String dmanbr; //记账子单元名称 private String dmanam; //=================以下字段为非必填 //额度控制标志 //空:默认 Y,Y:允许透支 N:不允许透支 private String ovrctl; //退票处理方式 //空:默认 N,Y: 退回原记账子单元 N:退回结算户 private String bcktyp; //余额非零时是否可关闭 //Y:可关闭, N:不可关闭 空:默认 Y private String clstyp; } 3、这是调用银行接口的工具类,一般就用“commonRequestMethod”方法 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.text.SimpleDateFormat; import java.util.*; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang.StringUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.jeecg.common.util.ReflectHelper; import org.jeecg.modules.cmb.dto.*; import org.jeecg.modules.cmb.entity.CMBBase64; import org.jeecg.modules.cmb.entity.CMBRequest; import org.jeecg.modules.cmb.entity.CMBRestBuilder; import org.jeecg.modules.cmb.enums.CMBTransAction; /** * 调用银行接口工具类 * * @author:user * @date: 2022-03-24 11:50 */ public class CMBUtils { static String pubkeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5Ec7viMyQC5SShRz1jP0IQRLLVGDQ4f1rgZwtxT4ZOgnWxUoAHquj2yIrgFjNpWVnt/1dJGtXWkpp2UN3jMI5ubjVQkL0OFD+8r0IFXYAARsCLAwVLF0LE487KvVRaQC7A7rPlFfBtE/v++KajzMuDauNlIASYobcFKYdZ89vIfE/xMg/44QJqQ2XBkoMnJ7ul0kMdh4YWOQnO0qqvXD2eK3KPaXMRtxieGsVBgsvtETprw98bTl9tPUBUrneyirrccS8/Z6raV6nioyx2RzrMld8YnjlnV2YTJpNAlG+y/wLoKY55Rkjcvg9wSe8qbI/VtYVQfQz8gfeUzFQTKKCwIDAQAB"; static String prikeyStr = "MIIEowIBAAKCAQEAwN7xTseqQs1pNA/+gTgXRqcxCYfkxDTsckfqf3O2ndsvJS5T" + "8Fb0oHTyjy0HjrKLASWWUKfhQGXPHbo1FQd+0TyHxSza55+HtXquUq7QsAITHCu3" + "U7aslvC7xe6/2E7nhu1TausF1nSyB1o4xVEjZyjrdQpTID0JvG8BtA5Yem9YDBCM" + "ZHBxvarQHVqdBsqo2G3M09qeUDbY3DuBgdiVAw0ApIM8mKGj4jsWmRSnypuxl40B" + "jWAr6Xgk44MpSGHndhiFXGvfMRRYEd8Z30w32QlB+Gjk8rQwXnvxG8YCBPYqXVkq" + "wld81bHFFz5zHQ0qekPhD8RrFimPn+RaD9VNfwIDAQABAoIBAQCxUUZQw0hJOkgq" + "UToO2t6rWjK/LGyp5m4rcuqoWl3eKxDhAgKxx4AHtPz7nM6B5qvdVg0oAfAZIICW" + "OAdtWgLBowC/yklHAWfm9O8nnQjHiGDBWX+mOx/ZdWFsy98cow5BAhfbCE/Jpme2" + "UsA2yC3gPcKbS+64iOVWlEfgnf/CLte/dE0eAMfsp5wXpwv3ygA4wtyd2X2P+y6s" + "+WYBKSvNMS08W4dsxwU9Q3AG3hS0Uab09qIPNS8tEMZ2L1tl0/VvkrAYjayM1CcK" + "CrSnwtH6eJVi4WQxL1K3QxyxDKucsOlqSHg++4VMpGZNpvstn3IsY3PyCgfsODvH" + "aoygvDBhAoGBAPxxdcI9stK9bIGSms0FqbVXYj8WmAjE/M9B7ECToWRQg65Gf8MY" + "PyUSkY2mbDHwf+yPsUb5Oli+a2GW8BwmJWeXEIy0lQxa1TS2b7CN6XJtZVnjEgiZ" + "d7bXy/j69r/C4CMlfbrRWnUGftKr/U7ynaGs10/bISeW12E7WdLV5+kDAoGBAMOW" + "nEzAFMPFzG9p/GtYpWU5jMNSiakzfm6n9Nwr7dFGnLhVGtO6act1bm/WB26NAgIE" + "ArhcitoKrI346nfkoZLXBpzzyJgFx4r31d1RN9Vsrt6AEywlwnLwHk2HXtCwmqre" + "hZ4I741S2rHlaT8ifNwLyjW2sbw9QnpC3RL7R3rVAoGAOI/Dbs4cLxO6KB4NCTrn" + "l3YI0VHiprRcYKPIp39sfel8V6P8JF5eZ5QNgMt1GotkXkCj298jr5aawLbs/aGe" + "Z+N1FdGwQ6BmfPUTeV+SmszgFI/IDp00MYeQcCzq9HRZfAZ+cUlPF0FpURKwIuxB" + "XWQ4qe/TMeeeQm7l5VOALrkCgYAljLa5LW9PHpxfD3P8j+pBAsl5flEbgN1XFTu3" + "QV/I+8t+wCgEWheRjhwDsI2AteWayXZUOsAVmFMEdrNdDTHP5SRJ4auzM/jZPzd5" + "4+vaN6Fi6ifEJAOu2VaX/9M+MYmgIFR6wLBs62k9GhQYoOBjxoetxENfJkuq+UdE" + "K6XPeQKBgFvf+SUrg7hFpRRyCq+DehdMQk1TJnEPTNLOalfrA/319KA8LGa0Q+ay" + "5c2mDc9F//yAJEAT1WTEqHnvKBQvjofFAGRntoCT8anAnskSytwwpltKqDcpoKx/" + "hVK+eVL47wuFroCBLGj0Zm3I7S+saGGmVllEky4jceE7IMTN7i6W"; private static PrivateKey privateKey; private static PublicKey publicKey; static String UID = "N002985759"; static String URL = "http://99.12.250.6:9080/cdcserver/api/v2"; static String AESKEY = "YSqdwE8vAQ1BcfYCpESUsnVzOOMA2ZSd"; public static void main(String[] args) throws Exception { // TODO Auto-generated method stub try { BankConfigDto bankConfigDto = new BankConfigDto(); bankConfigDto.setPubkeyStr(pubkeyStr); bankConfigDto.setPrikeyStr(prikeyStr); bankConfigDto.setAESKEY(AESKEY); bankConfigDto.setUID(UID); bankConfigDto.setURL(URL); // //============================新增记账子单元 接口测试================================ NTDMAADDParam ntdmaaddParam = new NTDMAADDParam(); ntdmaaddParam.setAccnbr("769900019310827"); ntdmaaddParam.setDmanbr("10101"); ntdmaaddParam.setDmanam("测试嘿嘿"); List ntdmaaddx = new ArrayList(); ntdmaaddx.add(ntdmaaddParam); //拼接银行请求body里面的参数 Map body = new HashMap(); body.put("ntdmaaddx", ntdmaaddx); //接口funcode参数 String funcode = "NTDMAADD"; List requestEmptyFiledList = Arrays.asList("ovrctl", "bcktyp", "clstyp"); JSONObject jsonObject4 = commonRequestMethod(bankConfigDto, funcode, body, requestEmptyFiledList, "参数【body】"); System.out.println("jsonObject4 " + jsonObject4); } catch (Exception e) { e.printStackTrace(); } } /** * 银行接口公共请求方法 * @param bankConfigDto 银行相关配置 * @param funcode 银行接口的funcode * @param body 银行接口的body属性值,目前只有Object和Map两种类型 * @param emptyFiledList body属性中可以为空的属性值,没有传null * @param message 在为空的基础上,前面添加的提示信息,没有传null * @return * @throws Exception */ public static JSONObject commonRequestMethod(BankConfigDto bankConfigDto, String funcode, T body, List emptyFiledList, String message) throws Exception { //校验body参数 checkBody(body, emptyFiledList, message); return DoProcessMyself(bankConfigDto, funcode, body); } //15位真实账号+10位记账子单元编号(长度可小于10位)=25位交易识别账号,可用于对外收款,并实现自动记账功能。(交易识别不支持外币)。 public static void modifySubAcc( SubAccUpdateDto updateDto) throws Exception { init(); JSONObject jsonObject = new JSONObject(); CMBRequest request = new CMBRestBuilder().of(updateDto).build(CMBTransAction.AccMgt_UPDATE, UID); jsonObject.put("request", request); DoProcess(JSONObject.parseObject(jsonObject.toJSONString()), privateKey); } /** * 获取主账号15位 * @param accno25 * @return */ public static String getMainAcc2Accnbr(String accno25){ return accno25.substring(0,15); } public static String getYurrefNoByReceiptName(String receiptName){ return receiptName.substring(receiptName.lastIndexOf("_")+1,receiptName.lastIndexOf(".")); } //etytim 的格式是一个把是时分秒连起来的格式 但是数据库要求有时分秒,所以这里做一下转化 public static String getDateStr(String dateStr){ return dateStr.substring(0,4)+"-"+dateStr.substring(4,6)+"-"+dateStr.substring(6,8); } public static String getEtytime(String etytim){ return etytim.substring(0,2)+":"+etytim.substring(2,4)+":"+etytim.substring(4,6); } /** * 获取账号编号主账号后半部分数据10位后的数据 * @param accno25 * @return */ public static String getSubAccUtil2Manbr(String accno25){ return accno25.substring(15); } /** * 判断银行调用结果是否成功 * @param responseJson 银行响应结果json * @return */ public static Boolean isSuccess(JSONObject responseJson) { return "SUC0000".equals(getCmbResponseParam(responseJson, "head", "resultcode")); } /** * 获取调用银行接口的响应参数值,不能通过该方法获取signature参数下的值 * @param responseJson 银行响应结果json * @param param1 要获取的结果参数名 (一级或者二级) * @param param2 要获取的结果参数名 (三级,没有可以为空,如果是body下的参数则一定要写正确) * @return */ public static String getCmbResponseParam(JSONObject responseJson, String param1, String param2) { JSONObject response = (JSONObject) responseJson.get("response"); checkParam(response, "返回结果中【response】为空或传入param1有误!"); JSONObject head = (JSONObject) response.get("head"); checkParam(head, "返回结果中【head】为空或传入param1有误!"); JSONObject body = (JSONObject) response.get("body"); checkParam(body, "返回结果中【body】为空或传入param1有误!"); //head下的参数 List param2List = Arrays.asList("bizcode", "funcode", "reqid", "resultcode", "resultmsg", "rspid", "userid"); JSONObject result = null; if ("response".equals(param1)) { result = response; } else if ("head".equals(param1)) { result = StringUtils.isNotBlank(param2) && param2List.contains(param2) ? (JSONObject) head.get(param2) : head; } else if ("body".equals(param1)) { result = StringUtils.isNotBlank(param2) && param2List.contains(param2) ? (JSONObject) body.get(param2) : body; } else { throw new RuntimeException("传入param2时param1不能为空!"); } return result.toString(); } /** * 获取请求参数json * @param bankConfigDto 银行接口参数,这里用来校验是否为空,这个方法只使用到了UID * @param funcode 接口code * @param body 请求json中的参数body,泛型类型 * @return */ public static JSONObject getRequestJson(BankConfigDto bankConfigDto, String funcode, T body) { checkBankConfig(bankConfigDto); checkParam(funcode, "funcode不能为空!"); String data = "{\"request\":{\"body\":" + JSON.toJSONString(body) + ",\"head\":{\"funcode\":\"" + funcode + "\",\"reqid\":\"" + getTimestamp() + "\",\"userid\":\"" + bankConfigDto.getUID() + "\"}}}"; return JSONObject.parseObject(data); } /** * 校验银行body参数 * @param body body参数 * @param emptyFiledList 可以为空的属性集合,为JavaBean的属性,没有可以为空的传null * @param message 在为空的基础上,前面添加的提示信息,没有传null */ public static void checkBody(T body, List emptyFiledList, String message) { if (body instanceof Map) { Map map = (Map) body; for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); List list = null; if (value instanceof List) { list = (List) value; } else { throw new RuntimeException("map集合中key为【" + key + "】的value值非法!应为List!"); } checkList(list, emptyFiledList, message); } } else { checkBean(body, emptyFiledList, message); } } /** * 校验参数集合 * @param list 参数集合 * @param emptyFiledList 可以为空的属性集合,为JavaBean的属性,没有可以为空的传null * @param message 在为空的基础上,前面添加的提示信息,没有传null */ public static void checkList(List list, List emptyFiledList, String message) { checkParam(list, (StringUtils.isBlank(message) ? "集合" : message) + "为空!"); for (int i = 0; i checkList(list, null, null); } /** * 校验参数集合 * @param list 参数集合 * @param emptyFiledList 可以为空的属性集合,没有传null */ public static void checkList(List list, List emptyFiledList) { checkList(list, emptyFiledList, null); } /** * 校验参数集合 * @param list 参数集合 * @param message 在为空的基础上,前面添加的提示信息,没有传null */ public static void checkList(List list, String message) { checkList(list, null, message); } /** * 校验javabean,传其他类型的对象可能会报错 * @param obj 校验的javabean * @param emptyFiledList 可以为空的属性集合,没有传null * @param message 在为空的基础上,前面添加的提示信息,没有传null */ public static void checkBean(Object obj, List emptyFiledList, String message) { checkParam(obj, (StringUtils.isBlank(message) ? "对象" : message) + "为空!"); //传入为空属性集合为null表示当前集合所有属性都不能为空,但为了做校验,emptyFiledList也不能为null //在这里做校验可以减少http请求 emptyFiledList = null != emptyFiledList ? emptyFiledList : new ArrayList(); List objectInfoList = ReflectHelper.getFiledsInfo(obj); for (Map objectInfo : objectInfoList) { String name = (String) objectInfo.get("name"); //对象属性名,属性名都是字符串 //可以为空的属性不做校验 if (!emptyFiledList.contains(name)) { //校验对象属性值是否为空 checkParam(objectInfo.get("value"), (StringUtils.isBlank(message) ? "对象的" : message + "的") + "【" + name + "】属性为空!"); } } } /** * 校验javabean,传其他类型的对象可能会报错 * @param obj 校验的javabean */ public static void checkBean(Object obj) { checkBean(obj, null, null); } /** * 校验javabean,传其他类型的对象可能会报错 * @param obj 校验的javabean * @param emptyFiledList 可以为空的属性集合 */ public static void checkBean(Object obj, List emptyFiledList) { checkBean(obj, emptyFiledList, null); } /** * 校验javabean,传其他类型的对象可能会报错 * @param obj 校验的javabean * @param message 在为空的基础上,前面添加的提示信息 */ public static void checkBean(Object obj, String message) { checkBean(obj, null, message); } /** * 校验参数是否为空 * @param obj 参数 * @param message 提示信息 */ public static void checkParam(Object obj, String message) { if (obj instanceof String) { if (StringUtils.isBlank((String) obj)) throw new RuntimeException(message); } Optional.ofNullable(obj).orElseThrow(() -> new RuntimeException(message)); } /** * 校验银行配置是否为空 * @param bankConfigDto 银行配置 */ public static void checkBankConfig(BankConfigDto bankConfigDto) { checkParam(bankConfigDto, "传入银行配置为空!"); checkParam(bankConfigDto.getPubkeyStr(), "银行公钥为空!"); checkParam(bankConfigDto.getPrikeyStr(), "银行私钥为空!"); checkParam(bankConfigDto.getAESKEY(), "银行AESKEY为空!"); checkParam(bankConfigDto.getAESKEY(), "银行UID为空!"); checkParam(bankConfigDto.getURL(), "银行接口路径为空!"); // Optional.ofNullable(bankConfigDto.getPayacc()).orElseThrow(() -> new RuntimeException("银行付方账号为空!")); // Optional.ofNullable(bankConfigDto.getBusmod()).orElseThrow(() -> new RuntimeException("银行模式编号为空!")); // Optional.ofNullable(bankConfigDto.getGrtflg()).orElseThrow(() -> new RuntimeException("银行网银审批标志为空!")); // Optional.ofNullable(bankConfigDto.getBbknbr()).orElseThrow(() -> new RuntimeException("银行分行号为空!")); } //这是用来获取时间戳的方法,用来生成唯一的银行接口参数reqid public static String getTimestamp() { SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");//设置日期格式 String date = df.format(new Date());// new Date()为获取当前系统时间,也可使用当前时间戳 Random random = new Random(); int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000; // System.out.println(rannum); String rand = date + rannum; System.out.println(rand); // SimpleDateFormat df2 = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式 // String date2 = df2.format(new Date());// new Date()为获取当前系统时间,也可使用当前时间戳 // System.out.println(date2); return rand; } //============================这里开始是银行的相关类 public static void init() throws Exception { Security.addProvider(new BouncyCastleProvider()); publicKey = getPublicKeyFromBytes(pubkeyStr); privateKey = getPrivateKeyFromBytes(prikeyStr, "PKCS"); } //这是经过自己加工的DoProcess方法 public static JSONObject DoProcessMyself(BankConfigDto bankConfigDto, String funcode, T body) throws Exception { //这个方法放在前面是为了校验参数 JSONObject jObject = getRequestJson(bankConfigDto, funcode, body); //要先执行初始化的方法,不然调用银行接口会报错 init(); JSONObject object = new JSONObject(); // 签名 object.put("sigdat", "__signature_sigdat__"); object.put("sigtim", GetTime()); //object.put("sigtim", "20191023165900"); jObject.put("signature", object); String source = serialJsonOrdered(jObject); System.out.println(source); String data = signRsa2048(source.getBytes(), getPrivateKeyFromBytes(bankConfigDto.getPrikeyStr(), "PKCS")); object.put("sigdat", data); jObject.put("signature", object); // AES加密 //因为在前面校验过了,这里直接使用 byte[] AESBytes = bankConfigDto.getAESKEY().getBytes(); String AesPlainxt = serialJsonOrdered(jObject); System.out.println("加密前req: " + AesPlainxt); String req = encryptAES256Str(AesPlainxt, AESBytes); System.out.println("加密后req: " + req); //发送请求 HashMap map = new HashMap(); map.put("UID", bankConfigDto.getUID()); map.put("FUNCODE", funcode); //银行最近新增的 map.put("DATA", URLEncoder.encode(req, "utf-8")); String res = doPostForm(bankConfigDto.getURL(), map); System.out.println("请求结果 res: " + res); //返回结果中包含这个两个字符,可能是没有白名单,也可能用户没有权限,或者其他错误 if ((res.contains("CDCServer:") && res.contains("ErrMsg:"))) { throw new RuntimeException(res); } //解密请求 String resplain = decryptAES256(res, AESBytes, true); System.out.println("res decrypt: " + resplain); JSONObject object2 = JSONObject.parseObject(resplain); JSONObject object3 = object2.getJSONObject("signature"); String resSign = object3.getString("sigdat"); object3.put("sigdat", "__signature_sigdat__"); object2.put("signature", object3); String resSignSource = serialJsonOrdered(object2); System.out.println("验签原文: " + resSignSource); System.out.println("验签签名值: " +resSign); Boolean verify = signRsa2048Verify(resSignSource.getBytes(), CMBBase64.decode(resSign), getPublicKeyFromBytes(bankConfigDto.getPubkeyStr())); System.out.println("验签结果: " + verify); return JSONObject.parseObject(resSignSource); } //这是原始的DoProcess public static String DoProcess(JSONObject jObject, PrivateKey prikey) throws Exception { JSONObject object = new JSONObject(); // 签名 object.put("sigdat", "__signature_sigdat__"); object.put("sigtim", GetTime()); //object.put("sigtim", "20191023165900"); jObject.put("signature", object); String source = serialJsonOrdered(jObject); System.out.println(source); String data = signRsa2048(source.getBytes()); object.put("sigdat", data); jObject.put("signature", object); // AES加密 String AesPlainxt = serialJsonOrdered(jObject); System.out.println("加密前req: " + AesPlainxt); String req = encryptAES256Str(AesPlainxt, AESKEY.getBytes()); System.out.println("加密后req: " + req); //发送请求 HashMap map = new HashMap(); map.put("UID", UID); map.put("DATA", URLEncoder.encode(req, "utf-8")); String res = doPostForm(URL, map); System.out.println("发送请求 res: " + res); //解密请求 String resplain = decryptAES256(res, AESKEY.getBytes(), true); System.out.println("res decrypt: " + resplain); JSONObject object2 = JSONObject.parseObject(resplain); JSONObject object3 = object2.getJSONObject("signature"); String resSign = object3.getString("sigdat"); object3.put("sigdat", "__signature_sigdat__"); object2.put("signature", object3); String resSignSource = serialJsonOrdered(object2); System.out.println("验签原文: " + resSignSource); System.out.println("验签签名值: " +resSign); Boolean verify = signRsa2048Verify(resSignSource.getBytes(), CMBBase64.decode(resSign), publicKey); System.out.println("验签结果: " + verify); return resSignSource; } public static String GetTime() { Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); return dateFormat.format(date); } public static String GetTime(String datePattern) { Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern); return dateFormat.format(date); } public static String encryptAES256Str(String content, byte[] bytePassword) { return CMBBase64.encode(encryptAES256(content, bytePassword)); } public static byte[] encryptAES256(String content, byte[] bytePassword) { try { Cipher cipherInstance = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC"); SecretKeySpec key = new SecretKeySpec(bytePassword, "AES"); cipherInstance.init(Cipher.ENCRYPT_MODE, key); byte[] byteContent = content.getBytes(); byte[] cryptograph = cipherInstance.doFinal(byteContent); return cryptograph; } catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); } return bytePassword; } public static String decryptAES256(String content, byte[] bytePassword, boolean logError) { if (content == null || content.length() == 0) { System.out.println("decryptAES256 param content is null or empty"); } byte[] bContent = null; try { bContent = CMBBase64.decode(content); } catch (Exception e) { System.out.println("decryptAES256 appear error"); e.printStackTrace(); } try { Cipher cipherInstance = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC"); SecretKeySpec key = new SecretKeySpec(bytePassword, "AES"); cipherInstance.init(Cipher.DECRYPT_MODE, key); byte[] crypted = cipherInstance.doFinal(bContent); return new String(crypted, "utf-8"); } catch (Exception e) { System.out.println(e.getMessage()); } return content; } public static String signRsa2048(byte[] baSource) throws Exception { try { Signature signature = Signature.getInstance("SHA256WithRSA"); signature.initSign(privateKey); signature.update(baSource); return CMBBase64.encode(signature.sign()); } catch (Exception e) { System.out.println("signRsa2048 appear error " + e.getMessage()); throw new Exception("signRsa2048 appear error " + e.getMessage()); } } public static String signRsa2048(byte[] baSource, PrivateKey prvKey) throws Exception { try { Signature signature = Signature.getInstance("SHA256WithRSA"); signature.initSign(prvKey); signature.update(baSource); return CMBBase64.encode(signature.sign()); } catch (Exception e) { System.out.println("signRsa2048 appear error" + e.getMessage()); throw new Exception("signRsa2048 appear error " + e.getMessage()); } } public static boolean signRsa2048Verify(byte[] baSource, byte[] baSignature, PublicKey pubKey) throws Exception { try { Signature signature = Signature.getInstance("SHA256WithRSA"); signature.initVerify(pubKey); signature.update(baSource); return signature.verify(baSignature); } catch (Exception e) { System.out.println("验签失败 " + e.getMessage()); throw new Exception("验签失败 " + e.getMessage()); } } public static PrivateKey getPrivateKeyFromBytes(String crtBase64, String type) throws Exception { // type = PKCS,X509 try { byte[] baKey = CMBBase64.decode(crtBase64); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey prvkey = keyFactory.generatePrivate(type.equals("PKCS") ? new PKCS8EncodedKeySpec(baKey) : new X509EncodedKeySpec(baKey)); return prvkey; } catch (Exception e) { throw new Exception("getPrivateKeyFromBytes error" + e.getMessage()); } } public static PublicKey getPublicKeyFromBytes(String crtBase64) throws Exception { try { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(CMBBase64.decode(crtBase64)); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(keySpec); return key; } catch (Exception e) { throw new Exception("getPublicKeyFromBytes error" + e.getMessage()); } } public static String doPostForm(String httpUrl, Map param) { HttpURLConnection connection = null; InputStream is = null; OutputStream os = null; BufferedReader br = null; String result = null; try { URL url = new URL(httpUrl); // trustAllHttpsCertificates(); SSLContext sslcontext; sslcontext = SSLContext.getInstance("SSL", "SunJSSE"); sslcontext.init(null, new TrustManager[] { new MyX509TrustManager() }, new java.security.SecureRandom()); // URL url = new URL("https://xxxx"); HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() { public boolean verify(String s, SSLSession sslsession) { System.out.println("WARNING: Hostname is not matched for cert."); return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier); HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory()); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setConnectTimeout(15000); connection.setReadTimeout(60000); connection.setInstanceFollowRedirects(true); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); os = connection.getOutputStream(); os.write(createLinkString(param).getBytes()); if (connection.getResponseCode() != 200) { is = connection.getErrorStream(); br = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuffer sbf = new StringBuffer(); String temp = null; while ((temp = br.readLine()) != null) { sbf.append(temp); sbf.append("\r\n"); } result = sbf.toString(); } else { is = connection.getInputStream(); br = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuffer sbf = new StringBuffer(); String temp = null; while ((temp = br.readLine()) != null) { sbf.append(temp); sbf.append("\r\n"); } result = sbf.toString(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } connection.disconnect(); } return result; } public static String createLinkString(Map params) throws UnsupportedEncodingException { ArrayList keys = new ArrayList(params.keySet()); Collections.sort(keys); StringBuilder prestr = new StringBuilder(); for (int i = 0; i prestr.append(key).append("=").append(value); } else { prestr.append(key).append("=").append(value).append("&"); } } return prestr.toString(); } public static String serialJsonOrdered(JSONObject json) { StringBuilder appender = new StringBuilder(); appender.append("{"); Iterator keys = new TreeSet(json.keySet()).iterator(); boolean isFirstEle = true; while (keys.hasNext()) { if (!isFirstEle) { appender.append(","); } String key = keys.next(); Object val = json.get(key); if (val instanceof JSONObject) { appender.append("\"").append(key).append("\":"); appender.append(serialJsonOrdered((JSONObject) val)); } else if (val instanceof JSONArray) { JSONArray jarray = (JSONArray) val; appender.append("\"").append(key).append("\":["); boolean isFirstArrEle = true; for (int i = 0; i appender.append(","); } Object obj = jarray.get(i); if (obj instanceof JSONObject) { appender.append(serialJsonOrdered((JSONObject) obj)); } else { appender.append(obj.toString().replaceAll("\"", "\\\\\"")); } isFirstArrEle = false; } appender.append("]"); } else { String value = ""; if (val instanceof String) { value = "\"" + val.toString().replaceAll("\"", "\\\\\"") + "\""; } else { value = val.toString().replaceAll("\"", "\\\\\""); } appender.append("\"").append(key).append("\":").append(value); } isFirstEle = false; } appender.append("}"); return appender.toString(); } } class MyX509TrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } } 4、工具类CMBBase64 import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Base64; import java.util.Map; public class CMBBase64 { static { String errorString = "Failed manually overriding key-length permissions."; int newMaxKeyLength; try { if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) throw new RuntimeException(errorString, e); } if (newMaxKeyLength StringBuilder sb = new StringBuilder(); int len = data.length; for (int i = 0; i sb.append(ENCODE_CHARS[b1 >>> 2]); sb.append(ENCODE_CHARS[(b1 & 3) byte data[] = str.getBytes(); int len = data.length; ByteArrayOutputStream buf = new ByteArrayOutputStream(len); for (int i = 0; i b3 = data[i++]; if (b3 == 61) return buf.toByteArray(); b3 = DECODE_CHARS[b3]; } while (i 2); int b4; do { b4 = data[i++]; if (b4 == 61) return buf.toByteArray(); b4 = DECODE_CHARS[b4]; } while (i -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 }; public static String baseConvertStr(String str) { if(null != str){ Base64.Decoder decoder = Base64.getDecoder(); try { return new String(decoder.decode(str.getBytes()), "GBK"); } catch (UnsupportedEncodingException e) { return null; } } return null; } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有