银商TMS平台秘钥下载工具
时间:2022-07-22
本文章向大家介绍银商TMS平台秘钥下载工具,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication3.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
import static javaapplication3.utils.DesUtil.DES_decrypt_3;
import static javaapplication3.utils.DesUtil.DES_encrypt_3;
import static javaapplication3.utils.HttpClientUtil.sendPost;
import static javaapplication3.utils.MyUtil.bytesToHexString;
import static javaapplication3.utils.MyUtil.hexStringToBytes;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* @author yangyongzhen 2018.11.12
* 连接银联商务TMS平台,进行秘钥激活,参数下载,和主秘钥下载功能
* 秘钥激活:功能是通过主控秘钥分量1获取主控秘钥分量2并解密出分量2的明文
* 参数下载:功能是使用主控秘钥分量2加密请求,获取商户号,终端号等信息
* 主秘钥下载:功能是下载银商通信的主秘钥
*/
public class TmsUtil {
public static Log log = LogFactory.getLog(HttpClientUtil.class);
//TMS地址 秘钥激活
public static String url_keyactive = "http://xx.xx.x.x../TMSWebService/nostandard/xxxx";
//TMS地址 主控秘钥下载
public static String url_keydownload = "http://xxxxxx/TMSWebService/nostandard/xxxx";
//TMS地址 参数更新检查
public static String url_updatecheck = "http://xxxxxx/TMSWebService/nostandard/xxxx";
public static String fid = "xxx";
public static String mid = "xxxx";
//硬件序列号(终端poscode)
//String sn = "xxx18030710022";
public static String sn = "xxxxxx710023";
//随机数
public static String random = "5183683762638030";
//秘钥分量1,通过银商的串口工具获取。
//String tmskey1 = "xxxxxxFDExx7E60D692AEC878E047D";
public static String tmskey1 = "xxxxxx3EAFCD367D4A4C1E";
//秘钥分量2,通过访问TMS系统接口的秘钥激活,获取密文,并用分量1解密得到。
public static String tmskey2 = "";
//交易类型
public static String transcode = "";
/**
* 异或运算
*
* @param src
* @param dest
* @param size
*/
private static void dataXor(byte[] src, byte[] dest, int size) {
for (int i = 0; i < size; i++) {
src[i] = (byte) ((dest[i] & 0xff) ^ (src[i] & 0xff));
}
}
/**
* 接入TMS平台报文头的认证信息计算
*
* @param random 随机数
* @param fid 厂商号
* @param mid 机器型号
* @param sn 硬件序列号(终端号)
* @param tmskey1 主控秘钥分量1(从银商提供的串口工具中获得)
* @return
*/
public static String calcAuthInfo(String random, String fid, String mid, String sn, String tmskey1) {
//计算认证信息
String auinfo = fid + mid + sn;
//使用认证密钥对厂商标识+终端型号标识+终端硬件序列号(使用 0x00 补足 8 的倍数长度)进行 CBC 运算得到加密结果(8 字节)
int auinfolen = auinfo.length();
int auinfoloop = auinfolen / 8;
if ((auinfolen % 8) > 0) {
auinfoloop++;
}
byte[] aubuf = new byte[auinfoloop * 8];
System.arraycopy(auinfo.getBytes(), 0, aubuf, 0, auinfolen);
byte[] authkey = DES_encrypt_3(random.getBytes(), hexStringToBytes(tmskey1));
byte[] auinfoI = new byte[8];
byte[] auinfoD = new byte[8];
for (int i = 0; i < auinfoloop; i++) {
System.arraycopy(aubuf, i * 8, auinfoD, 0, 8);
dataXor(auinfoI, auinfoD, 8);
auinfoI = DES_encrypt_3(auinfoI, authkey);
}
String authinfo = EncryptionUtils.base64Encode(auinfoI);
return authinfo;
}
public static void main(String[] args) {
log.debug("Begin TMS test...");
Map<String, String> headers = new HashMap<String, String>();
JSONObject data = null;
headers.put("VER", "01");
headers.put("Encoding", "UTF8");
headers.put("content-type", "application/json");
headers.put("FID", fid);
headers.put("MID", mid);
headers.put("SN", sn);
headers.put("Random", random);
//1.===========================秘钥激活测试
log.debug("1.==================秘钥激活");
String authinfo = "";
transcode = "020";
authinfo = calcAuthInfo(random, fid, mid, sn, tmskey1);
headers.put("AuthInfo", authinfo);
headers.put("TransCode", transcode);
String out = sendPost(url_keyactive, headers, data);
log.debug(out);
JSONObject jbt = JSONObject.parseObject(out);
String rcode = "";
rcode = jbt.getString("ReturnCode");
if (rcode.equals("00")) {
log.debug("秘钥激活成功!");
log.debug(jbt);
String key2 = jbt.getString("MKey2");
log.debug("秘钥分量2密文: " + key2);
//使用主控秘钥分量1对其进行解密
byte[] outkey = DES_decrypt_3(hexStringToBytes(key2), hexStringToBytes(tmskey1));
tmskey2 = bytesToHexString(outkey);
log.debug("秘钥分量2明文: " + tmskey2);
//2.===========================参数更新检查,参数下载(商户号,终端号等参数在里面)
log.debug("2.==================参数更新检查");
String poststr = "{"
+ ""APPCount":1,"
+ ""APP1":"
+ "{"APPID":"NC_B503","APPVer":"V0.02.13","APPIndex":"1","APPState":"1","
+ ""ParameterUp":{"04000001":"1"},"
+ ""Parameter":["01000001","01000002","01000005","02000002","03000012","04000001","04000002","04000003","04000006","04000007","04000008","04000012","04000013","04000014","04000015","04000016","04000017","04000022","04000023","04000026","04000028","04000029","04000030","04000031","04000038","04000039","04000051","04000054","04000055","04000056","deptcode"]}}";
transcode = "010";
//使用tmskey2计算认证信息,tmskey1则只在第一步的秘钥激活中有用
authinfo = calcAuthInfo(random, fid, mid, sn, tmskey2);
headers.remove("TransCode");
headers.remove("AuthInfo");
headers.put("TransCode", transcode);
headers.put("AuthInfo", authinfo);
log.debug("poststr:" + poststr);
data = JSON.parseObject(poststr);
log.debug("data:" + data);
out = sendPost(url_updatecheck, headers, data);
jbt = JSONObject.parseObject(out);
rcode = jbt.getString("ReturnCode");
if (rcode.equals("00")) {
log.debug("参数更新检查成功!");
log.debug(jbt);
} else {
log.debug("参数更新检查失败!");
log.debug(jbt);
}
} else {
log.debug("秘钥激活失败!");
log.debug(jbt);
}
//3.===========================银商主秘钥下载
log.debug("3.==================主秘钥下载");
transcode = "030";
//使用tmskey2计算认证信息,tmskey1则只在第一步的秘钥激活中有用
authinfo = calcAuthInfo(random, fid, mid, sn, tmskey2);
headers.remove("TransCode");
headers.remove("AuthInfo");
headers.put("TransCode", transcode);
headers.put("AuthInfo", authinfo);
out = sendPost(url_keydownload, headers, data);
jbt = JSONObject.parseObject(out);
rcode = jbt.getString("ReturnCode");
if (rcode.equals("00")) {
log.debug("主秘钥下载成功!");
log.debug(jbt);
//使用秘钥分量2,解密出主秘钥
} else {
log.debug("主秘钥下载失败!");
log.debug(jbt);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication3.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
/**
* @ClassName: HttpClientUtil
* @Description: TODO(HttpClient工具类)
* @author wangxy
* @date 2018年5月8日 下午5:23:39
* @version 1.0
*/
public class HttpClientUtil {
// 默认字符集
private static final String ENCODING = "UTF-8";
public static Log log = LogFactory.getLog(HttpClientUtil.class);
/**
* @Title: sendPost
* @Description: TODO(发送post请求)
* @param url 请求地址
* @param headers 请求头
* @param data 请求实体
* @param encoding 字符集
* @author wangxy
* @return String
* @date 2018年5月10日 下午4:36:17
* @throws
*/
public static String sendPost(String url, Map<String, String> headers, JSONObject data, String encoding) {
log.info("进入post请求方法...");
log.info("请求入参:URL= " + url);
log.info("请求入参:headers=" + JSON.toJSONString(headers));
log.info("请求入参:data=" + JSON.toJSONString(data));
// 请求返回结果
String resultJson = null;
// 创建Client
CloseableHttpClient client = HttpClients.createDefault();
// 创建HttpPost对象
HttpPost httpPost = new HttpPost();
try {
// 设置请求地址
httpPost.setURI(new URI(url));
// 设置请求头
if (headers != null) {
Header[] allHeader = new BasicHeader[headers.size()];
int i = 0;
for (Map.Entry<String, String> entry : headers.entrySet()) {
allHeader[i] = new BasicHeader(entry.getKey(), entry.getValue());
i++;
}
httpPost.setHeaders(allHeader);
}
// 设置实体
httpPost.setEntity(new StringEntity(JSON.toJSONString(data)));
// 发送请求,返回响应对象
CloseableHttpResponse response = client.execute(httpPost);
// 获取响应状态
int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_OK) {
// 获取响应结果
resultJson = EntityUtils.toString(response.getEntity(), encoding);
} else {
log.error("响应失败,状态码:" + status);
}
} catch (Exception e) {
log.error("发送post请求失败", e);
} finally {
httpPost.releaseConnection();
}
return resultJson;
}
/**
* @Title: sendPost
* @Description: TODO(发送post请求,请求数据默认使用json格式,默认使用UTF-8编码)
* @param url 请求地址
* @param data 请求实体
* @author wangxy
* @return String
* @date 2018年5月10日 下午4:37:28
* @throws
*/
public static String sendPost(String url, JSONObject data) {
// 设置默认请求头
Map<String, String> headers = new HashMap<String, String>();
headers.put("content-type", "application/json");
return sendPost(url, headers, data, ENCODING);
}
/**
* @Title: sendPost
* @Description: TODO(发送post请求,请求数据默认使用json格式,默认使用UTF-8编码)
* @param url 请求地址
* @param params 请求实体
* @author wangxy
* @return String
* @date 2018年5月10日 下午6:11:05
* @throws
*/
public static String sendPost(String url, Map<String, Object> params) {
// 设置默认请求头
Map<String, String> headers = new HashMap<String, String>();
headers.put("content-type", "application/json");
// 将map转成json
JSONObject data = JSONObject.parseObject(JSON.toJSONString(params));
return sendPost(url, headers, data, ENCODING);
}
/**
* @Title: sendPost
* @Description: TODO(发送post请求,请求数据默认使用UTF-8编码)
* @param url 请求地址
* @param headers 请求头
* @param data 请求实体
* @author wangxy
* @return String
* @date 2018年5月10日 下午4:39:03
* @throws
*/
public static String sendPost(String url, Map<String, String> headers, JSONObject data) {
return sendPost(url, headers, data, ENCODING);
}
/**
* @Title: sendPost
* @Description:(发送post请求,请求数据默认使用UTF-8编码)
* @param url 请求地址
* @param headers 请求头
* @param params 请求实体
* @author wangxy
* @return String
* @date 2018年5月10日 下午5:58:40
* @throws
*/
public static String sendPost(String url, Map<String, String> headers, Map<String, String> params) {
// 将map转成json
JSONObject data = JSONObject.parseObject(JSON.toJSONString(params));
return sendPost(url, headers, data, ENCODING);
}
/**
* @Title: sendGet
* @Description: TODO(发送get请求)
* @param url 请求地址
* @param params 请求参数
* @param encoding 编码
* @author wangxy
* @return String
* @date 2018年5月14日 下午2:39:01
* @throws
*/
public static String sendGet(String url, Map<String, Object> params, String encoding) {
log.info("进入get请求方法...");
log.info("请求入参:URL= " + url);
log.info("请求入参:params=" + JSON.toJSONString(params));
// 请求结果
String resultJson = null;
// 创建client
CloseableHttpClient client = HttpClients.createDefault();
// 创建HttpGet
HttpGet httpGet = new HttpGet();
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
// 封装参数
if (params != null) {
for (String key : params.keySet()) {
builder.addParameter(key, params.get(key).toString());
}
}
URI uri = builder.build();
log.info("请求地址:" + uri);
// 设置请求地址
httpGet.setURI(uri);
// 发送请求,返回响应对象
CloseableHttpResponse response = client.execute(httpGet);
// 获取响应状态
int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_OK) {
// 获取响应数据
resultJson = EntityUtils.toString(response.getEntity(), encoding);
} else {
log.error("响应失败,状态码:" + status);
}
} catch (Exception e) {
log.error("发送get请求失败", e);
} finally {
httpGet.releaseConnection();
}
return resultJson;
}
/**
* @Title: sendGet
* @Description: TODO(发送get请求)
* @param url 请求地址
* @param params 请求参数
* @author wangxy
* @return String
* @date 2018年5月14日 下午2:32:39
* @throws
*/
public static String sendGet(String url, Map<String, Object> params) {
return sendGet(url, params, ENCODING);
}
/**
* @Title: sendGet
* @Description: TODO(发送get请求)
* @param url 请求地址
* @author wangxy
* @return String
* @date 2018年5月14日 下午2:33:45
* @throws
*/
public static String sendGet(String url) {
return sendGet(url, null, ENCODING);
}
public static void main(String[] args) {
log.debug("Begin Http test...");
}
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法