JAVA建行银企直连报文加解密
接上一篇密钥交换之后获得银行提供的:银行RSA签名公钥RSA.bank.public.key,接受报文验签使用;银行DES加密私钥DES.bank.private.key,加密报文使用。还有之前自己生成的RSA签名私钥RSA.private.key,报文签名使用。下面以签到为例把报文签名、加密以及接受报文后解密、验签写上:
签到http入口:
/*** @Auther qijw* @Date 2020/11/16* @Description:建行银企直连签到* @Version 1.0**/@ApiOperation(value = "建行银企直连签到", notes = "建行银企直连签到")@GetMapping("/CCBSignIn")public ResponseModel<JSONObject> signIn(){try {log.info("建行银企直连签到");RspSign signIn = signServiceImpl.signIn();JSONObject joo = new JSONObject();joo.put("signIn", signIn);return new ResponseModel<>(joo);} catch (Exception e){log.error("建行银企直连签到异常",e);return new ResponseModel<>(HttpStatus.INTERNAL_SERVER_ERROR.value(),HttpStatus.INTERNAL_SERVER_ERROR.name());}}
签到构造报文、签名、解析
/*** @Auther qijw* @Date 2020/11/16* @Description:签到构造报文、签名、解析* @Version 1.0**/
public RspSign sign(String sysCode) {try {log.info("建行银企直连签到sysCode:{}", sysCode);//构造请求报文String reqXml = getSign(sysCode);//签名,加密,发送请求String resultXml = signAndEncryp(reqXml);//解析响应return JaxbUtil.converyToJavaBean(resultXml, RspSign.class);} catch (Exception e) {log.error("建行银企直连签到异常", e);return null;}}
构造接口签到的请求报文,使用实体类bean传入P1OPME001、电子银行合约编号、时间等必要字段
/*** 构造接口签到的请求报文*/public String getSign(String sysCode) {try {log.info("建行银企直连签到报文");BankProperties BankProperties = new BankProperties();CCBSign cCBSign = new CCBSign();Head head = BankProperties.createHead();//签到P1OPME001,签退P1OPME002head.setSysTxCode(sysCode);cCBSign.setHead(head);String xmlStr = JaxbUtil.ojbectToXmlWithCDATA(BankConstants.elements, CCBSign.class, cCBSign);return xmlStr;} catch (Exception e) {log.error("建行银企直连签到报文出错,错误信息:" + e.getMessage(), e);return null;}}
签名,加密,发送请求,解析报文,验签
/*** 签名,加密,发送请求,解析报文,验签*/public String signAndEncryp(String reqXml) {try {//数字签名算法为:MD5withRSAString signature = RSASignUtil.sign(reqXml, bankKeyConfig.priRSAKey);//DESede (3DES):DES 对称密钥由银行生成,用于对交易报文和文件内容的加解密String data = DESedeUtil.encryptWithDESede(reqXml, bankKeyConfig.Des_KEY);//向建行银企直连发送请求String reqs = httpUtil.sendRequest(data, signature, CommonBankConstants.REQUEST_CHARSET_UTF8);if (null != reqs) {return reqs;} else {log.info("建行银企直连签名,加密,发送请求异常");}} catch (Exception e) {log.error("建行银企直连签名,加密,发送请求错误", e);return null;}return null;}
MD5withRSA签名
/*** MD5withRSA签名** @param data 待签名数据* @return 签名*/public static String sign(String data , String private_Key) throws Exception {byte[] keyBytes = getPrivateKey(private_Key).getEncoded();PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey key = keyFactory.generatePrivate(keySpec);Signature signature = Signature.getInstance("MD5withRSA");signature.initSign(key);signature.update(data.getBytes());return new String(Base64.encodeBase64(signature.sign()));}
DESede加密,还原密钥方法网上有。不知道的自己搜一下
public static final String KEY_ALGORITHM = "DESede";/*** 加密/解密算法 /工作模式 /填充方式* Java 6支持PKCS5PADDING填充方式* Bouncy Castle支持PKCS7Padding填充方式*/public static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";/*** DESede/ECB/PKCS5Padding加密* @param data 待加密数据* @param key 密钥* @return byte[] 加密数据* @throws Exception*/public static String encrypt(String data, String key) throws Exception{try {//还原密钥Key k = toKey(key);//加密Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, k);return Base64Util.getInstance().base64Encode(cipher.doFinal(data.getBytes("UTF-8")));} catch (Exception e){log.error("DESede加密错误",e);}return null;}
发送请求报文,获得返回报文,解密、验签
/*** 建行银企直连,发送请求报文,获得返回报文,解密、验签** @param data* @return*/public String sendRequest(String data, String signature, String charset) {log.info("请求建行银企直连请求报文请求参数:{}", data);HttpClient myclient = null;PostMethod httppost = null;String repcontent = "";try {myclient = new HttpClient(); // 构建http客户端httppost = new PostMethod(bankKeyConfig.bankServerUrl); // 加密端口httppost.addParameter("chanl_cust_no", bankKeyConfig.CHANL_CUST_NO);httppost.addParameter("xml", data);httppost.addParameter("signature", signature);log.info("发送给银企直连服务数据:{}",data);// 获得http返回码int returnFlag = myclient.executeMethod(httppost);InputStream postResult = httppost.getResponseBodyAsStream();byte[] bytes = inputStream2byte(postResult);byte[] len_byte = new byte[10];System.arraycopy(bytes,0,len_byte,0,10);repcontent = new String(len_byte);log.info("请求建行银企直连秘钥传输报文返回结果:{}", repcontent);//成功响应: 数字签名的长度(固定长度 10 个字节) +数字签名数据+加密后的数据。解密时应先根据前 10 位算出数字签名的长度,然后再截取数字签名及报文密文。if (null != bytes && repcontent.startsWith("00")) {//数字签名的长度(固定长度 10 个字节) +数字签名数据+加密后的数据int signLenth = Integer.valueOf(repcontent.substring(0, BankConstants.LENGTH));byte[] signByte = new byte[signLenth];System.arraycopy(bytes,10,signByte,0,signLenth);//返回后的签名String sign = new String(Base64.encodeBase64(signByte),"UTF-8");//加密后报文的长度int srcLength = bytes.length - signLenth - 10;byte[] scrByte = new byte[srcLength];System.arraycopy(bytes,signLenth + 10,scrByte,0,srcLength);//返回的解密后的报文repcontent = DESedeUtil.decrypt(scrByte, bankKeyConfig.Des_KEY);//将解密后的报文与签名验签if (null != repcontent && RSASignUtil.verify(sign, repcontent, bankKeyConfig.RSA_KEY)) {return repcontent;} else {log.error("请求建行银企直连验签出错:{} :{}", sign, repcontent);}}else {//失败响应: 6 位错误代码+错误信息,所有信息均不需要进行加密,以字节流返回。log.error("请求建行银企直连秘钥传输报文出错:",repcontent);return repcontent;}log.info("请求建行银企直连报文返回结果:{}", bytes);return repcontent;} catch (Exception e) {log.error("请求建行银企直连报文出错,错误信息:" + e.getMessage(), e);} finally {try {// 释放http连接httppost.releaseConnection();myclient.getHttpConnectionManager().closeIdleConnections(0);} catch (Exception e2) {log.error("银企直联释放http连接报错:{}", e2.getMessage());}myclient = null;httppost = null;}return null;}
byte[]数组用的比较少,如果有更好更简洁的方法请联系我,谢谢!
DES解密
/*** 解密* @param data 待解密数据* @param key 密钥* @return byte[] 解密数据* @throws Exception*/public static String decrypt(byte[] data, String key){try {//还原密钥Key k = toKey(key);//加密Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, k);return new String(cipher.doFinal(data));} catch (Exception e){log.error("DESede解密错误",e);System.out.printf("");}return null;}
RSA验签
/*** 验签** @param srcData 原始字符串* @param sign 签名* @return 是否验签通过*/public static boolean verify(String sign, String srcData ,String public_Key) throws Exception {byte[] keyBytes = getPublicKey(public_Key).getEncoded();X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey key = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance("MD5withRSA");signature.initVerify(key);signature.update(srcData.getBytes());return signature.verify(Base64.decodeBase64(sign.getBytes()));}
签到签退调试好了之后别的接口也很简单了,有什么不懂的可以给我留言!
JAVA建行银企直连报文加解密相关推荐
- JAVA建行银企直连密钥传输交换接口
建行银企直连密钥加解密传输 最近在做建行银企直连项目,给的接口文档描述的不清楚,在网上找了很久都没有一个能用的例子,在第一步密钥传输交换接口就调试了半个月才解决,下面我将加解密的代码发出来给后来人一些 ...
- java发送加密报文_RSA加密---从后台到客户端实现报文加解密
RSA是当前最流行的非对称加密方式,使用公钥加密使用密钥解密,如何妥善的保管密钥就成了关键. 动态生成密钥 工具类 package com.yitong.utils; import java.secu ...
- java aes javascript_Java已有AES加解密,现需要前端Javascript加密调接口,返回的数据需要解密,目前互通不了,找不到原因...
目前Javascript使用'crypto-js'包. 前后台可以自己跑通加解密,但是,无法互通. 针对对象{}加密--网上的方案,已经尝试了4天左右了,还没成功,请指导. 无思路,无报错. Java ...
- java aes ebc_Delphi XE2+标准AES加解密算法(AES/EBC,CBC/PKCS5Padding-base64)
[实例简介] 实现了AES/ECB/PKCS5Padding.AES/CBC/PKCS5Padding 密钥长度128/192/256bit,密钥0填充.是标准的AES算法,支持在线AES加解密网站互 ...
- java aes ctr_AES CBC和CTR加解密实例
http://www.metsky.com/archives/585.html 2012 AES(Advanced Encryption Standard,高级加密标准) 又叫Rijndael加密法, ...
- 报文加解密原理_加密系统的组成与过程
加密系统的组成与过程 来源:超时代软件 更新时间:2018年11月28日 18:16:55 数据库透明加密就是把数据信息即明文转换为不可辨识的形式即密文的过程,目的是使不应了解该数据信息的人不 ...
- Java使用PBE算法进行对称加解密最简入门和示例
PBE 算法 PBE( Password Based Encryption, 基于口密加密).PBE是一种基于口令的加密算法, 采用随机数杂凑(盐)多重加密方法保证数据安全性. PBE算法并没有真正构 ...
- java rsa enc 源码_RSA加解密源码 | 学步园
源码: #include #include #include #include #include #include #include typedef struct{ unsigned char enc ...
- java aes128位 cfb与gcm加解密 aes-128-cfb aes-128-gcm
Base64.encodeBase64String(secretKey.getEncoded())是apache的commons-codec库,二进制经base64编码为字符串 //cfb packa ...
最新文章
- linux——环境变量与文件查找
- varnish Cconfigure
- 构建之法之单元测试及设计流程
- 【渝粤题库】广东开放大学 人力资源管理 形成性考核
- VBA操作word生成sql语句
- WAMP本地环境升级php版本操作步骤(详细)
- apache poi excel显示 base64 图片_java操作Excel一:POI
- Mac中ElasticSearch安装
- DBeaver 离线安装
- 即将来临的Rails 4.0将放弃Ruby 1.8支持,改进后台任务、缓存等多项内容
- OSChina 周一乱弹 —— 无双什么都好,但不是芙妹
- C#高级编程——C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)——图文详解加源码
- VMware-KVM安装
- 鸿蒙第二批升级时间,鸿蒙系统第二批升级名单_鸿蒙系统第二批有哪些手机可以升级...
- 网站敏感骂人词库及算法(附6仟个敏感词)
- POI问题总结,关于数字级联及多级级联(三级以上)
- 2020.01.27 再见24号
- 开发直播平台直播系统软件app搭建流程解决方案
- Navicat工具怎么得到MySQL数据库EXCEL表结构
- 菜鸟学堂:新手应该掌握的Linux命令(转)