From 8b70bab6bcfbe3d88a943aeee259bfbf275b9d72 Mon Sep 17 00:00:00 2001 From: Xia Kaixiang Date: Mon, 8 Jul 2019 10:53:36 +0800 Subject: [PATCH] =?utf8?q?=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5=E6=8E=A5?= =?utf8?q?=E5=8F=A3=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../dlpay/framework/util/SysparaUtil.java | 4 + .../com/supwisdom/dlpay/util/DESedeUtil.java | 107 ++++++++++++++++++ .../dlpay/api/bean/api_request_param.kt | 53 +++++++++ .../dali_datasync_api_controller.kt | 63 +++++++++++ 5 files changed, 228 insertions(+) create mode 100644 src/main/java/com/supwisdom/dlpay/util/DESedeUtil.java create mode 100644 src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt diff --git a/build.gradle b/build.gradle index d9f0ca93..a0654a6e 100644 --- a/build.gradle +++ b/build.gradle @@ -59,6 +59,7 @@ dependencies { implementation 'org.springframework.social:spring-social-web:1.1.6.RELEASE' implementation 'org.jetbrains.kotlin:kotlin-reflect' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' + implementation 'commons-codec:commons-codec:1.12' implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery:2.1.2.RELEASE' diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/SysparaUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/SysparaUtil.java index 07e4aafd..3ccb2a70 100644 --- a/src/main/java/com/supwisdom/dlpay/framework/util/SysparaUtil.java +++ b/src/main/java/com/supwisdom/dlpay/framework/util/SysparaUtil.java @@ -13,6 +13,10 @@ public class SysparaUtil { public static final int SYSPARAID_NO1 = 1; //系统默认最大余额限制的ID public static final int SYSPARAID_NO2 = 2; //paraid=2 + public static final int SYSPARAID_NO2019 = 2019; //与卡管系统对接的应用ID + public static final int SYSPARAID_NO2020 = 2020; //与卡管系统对接的应用appkey + public static final int SYSPARAID_NO2021 = 2021; //与卡管系统对接的业务参数deskey + public static final double SYSPARA_NO1_DEFAULT = 10000.0; // 系统默认最大余额限制 } diff --git a/src/main/java/com/supwisdom/dlpay/util/DESedeUtil.java b/src/main/java/com/supwisdom/dlpay/util/DESedeUtil.java new file mode 100644 index 00000000..0d0e4cf0 --- /dev/null +++ b/src/main/java/com/supwisdom/dlpay/util/DESedeUtil.java @@ -0,0 +1,107 @@ +package com.supwisdom.dlpay.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; + +import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.UnsupportedEncodingException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +/** + * 加密/解密工具类 + */ +public class DESedeUtil { + /** + * 加密工具类唯一实例 + */ + private static DESedeUtil instance = null; + /** + * + */ + private Cipher cipher; + /** + * + */ + private SecretKey secretKey; + /** + * + */ + private IvParameterSpec ivSpec; + + /** + * 初始化、创建密钥数据 + * + * @throws NoSuchPaddingException + * @throws NoSuchAlgorithmException + */ + private DESedeUtil(String deskey) throws NoSuchAlgorithmException, NoSuchPaddingException { + byte[] keyData = Base64.decodeBase64(deskey); + String fullAlg = "DESede/CBC/PKCS5Padding"; + cipher = Cipher.getInstance(fullAlg); + int blockSize = cipher.getBlockSize(); + byte[] iv = new byte[blockSize]; + for (int i = 0; i < blockSize; ++i) { + iv[i] = 0; + } + secretKey = new SecretKeySpec(keyData, StringUtils.substringBefore(fullAlg, "/")); + ivSpec = new IvParameterSpec(iv); + } + + /** + * 获取唯一实例 + * + * @return + * @throws NoSuchPaddingException + * @throws NoSuchAlgorithmException + */ + public static DESedeUtil getInstance(String deskey) throws NoSuchAlgorithmException, NoSuchPaddingException { + if (null == instance) { + synchronized (DESedeUtil.class) { + if (null == instance) { + instance = new DESedeUtil(deskey); + } + } + } + return instance; + } + + /** + * 加密 + * + * @param s 待加密字符串 + * @return 返回BASE64编码加密字符串 + * @throws InvalidAlgorithmParameterException + * @throws InvalidKeyException + * @throws BadPaddingException + * @throws IllegalBlockSizeException + * @throws UnsupportedEncodingException + */ + public String encode(String s) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { + cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); + byte[] cipherBytes = cipher.doFinal(s.getBytes("UTF-8")); + return new String(Base64.encodeBase64(cipherBytes)); + } + + /** + * 解密 + * + * @param s 待解密字符串 + * @return 返回明文 + * @throws InvalidAlgorithmParameterException + * @throws InvalidKeyException + * @throws BadPaddingException + * @throws IllegalBlockSizeException + * @throws UnsupportedEncodingException + */ + public String decode(String s) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { + cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec); + byte[] resultBytes = cipher.doFinal(Base64.decodeBase64(s)); + return new String(resultBytes, "UTF-8"); + } + +} + diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt index 447a3f24..5568b6f1 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt @@ -1,8 +1,11 @@ package com.supwisdom.dlpay.api.bean +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.supwisdom.dlpay.exception.RequestParamCheckException import com.supwisdom.dlpay.framework.util.* import com.supwisdom.dlpay.util.ConstantUtil +import com.supwisdom.dlpay.util.DESedeUtil // ============================ USER ============================ // class OpenUserParam : APIRequestParam() { @@ -355,3 +358,53 @@ class CommonQueryRechargeResultParam : APIRequestParam() { } +class DaliDatasyncParam { + var app_id: String = "" + var data: String = "" + var count: Int = 0 + var timestamp: String = "" + var sign_type: String = "" + var sign: String = "" + + fun checkParam(): Boolean { + if (StringUtil.isEmpty(app_id)) throw RequestParamCheckException(2000, "请求参数错误[应用ID为空]") + if (StringUtil.isEmpty(data)) throw RequestParamCheckException(2000, "请求参数错误[业务参数报文为空]") + if (null == count || count < 1) throw RequestParamCheckException(2000, "请求参数错误[业务明细至少有一条]") + if (!DateUtil.checkDatetimeValid(timestamp, DateUtil.DATETIME_FMT)) throw RequestParamCheckException(2000, "请求参数错误[时间戳]") + if (StringUtil.isEmpty(sign_type) || !"HmacSHA256".equals(sign_type, true)) throw RequestParamCheckException(2000, "请求参数错误[签名算法]") + if (StringUtil.isEmpty(sign)) throw RequestParamCheckException(2000, "请求参数错误[签名为空]") + + return true + } + + fun checkSign(key: String): Boolean { + val signData = "app_id=$app_id&count=$count&data=$data×tamp=$timestamp" + return sign.equals(HmacUtil.HMACSHA256(signData, key), true) + } + + fun decData(deskey: String): ArrayList { + try { + val listType = object : TypeToken>() {}.type + val decstr = DESedeUtil.getInstance(deskey).decode(data) + return Gson().fromJson(decstr, listType) + } catch (e: Exception) { + throw RequestParamCheckException(1001, "数据解密失败!") + } + } + +} + +class DaliDatasyncDetail { + var cardno: String = "" + var cardphyid: String = "" + var expiredate: String = "" + var cardstatus: String = "" + var bankcardno: String? = null + var username: String = "" + var idtype: String = "" + var idno: String = "" + var mobile: String? = null + var email: String? = null +} + + diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt new file mode 100644 index 00000000..97562337 --- /dev/null +++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt @@ -0,0 +1,63 @@ +package com.supwisdom.dlpay.api.controller + +import com.supwisdom.dlpay.api.bean.DaliDatasyncParam +import com.supwisdom.dlpay.exception.RequestParamCheckException +import com.supwisdom.dlpay.framework.ResponseBodyBuilder +import com.supwisdom.dlpay.framework.service.SystemUtilService +import com.supwisdom.dlpay.framework.util.StringUtil +import com.supwisdom.dlpay.framework.util.SysparaUtil +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.* + +@RequestMapping("/api/common") +class DaliDatasyncApiController { + @Autowired + lateinit var systemUtilService: SystemUtilService + + /** + * ============================================================================ + * 大理卡管系统推送市民卡信息同步接口 + * ============================================================================ + * */ + @PostMapping("/datasync") + @ResponseBody + fun daliDatasync(@RequestBody param: DaliDatasyncParam): ResponseEntity { + try { + param.checkParam() + val appid = systemUtilService.getSysparaValue(SysparaUtil.SYSPARAID_NO2019) + val appkey = systemUtilService.getSysparaValue(SysparaUtil.SYSPARAID_NO2020) + val deskey = systemUtilService.getSysparaValue(SysparaUtil.SYSPARAID_NO2021) + if (StringUtil.isEmpty(appid) || StringUtil.isEmpty(appkey) || StringUtil.isEmpty(deskey)) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(1000, "系统参数未配置")) + } else if (appid != param.app_id) { + throw RequestParamCheckException(2000, "请求参数错误[应用ID错误]") + } + if (!param.checkSign(appkey)) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(2001, "签名错误")) + } + + val datalist = param.decData(deskey) + if (param.count != datalist.size) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(2002, "请求参数错误[数据条数不匹配]")) + } + + datalist.forEach { + TODO("更新数据逻辑") + } + + return return ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "SUCCESS")) + } catch (ex: RequestParamCheckException) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(ex.errCode, ex.message ?: "请求参数错误")) + } catch (e: Exception) { + e.printStackTrace() + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(4000, "系统处理错误")) + } + } + +} \ No newline at end of file -- 2.17.1