diff --git a/WebContent/Tenwa/Lease/Flow/Comm/LBIdentityCheck/LBCarIdentityCheck.jsp b/WebContent/Tenwa/Lease/Flow/Comm/LBIdentityCheck/LBCarIdentityCheck.jsp index fdfc238aa..27f1d4383 100644 --- a/WebContent/Tenwa/Lease/Flow/Comm/LBIdentityCheck/LBCarIdentityCheck.jsp +++ b/WebContent/Tenwa/Lease/Flow/Comm/LBIdentityCheck/LBCarIdentityCheck.jsp @@ -41,12 +41,13 @@ var customertype = "<%=customertype%>"; var relations=getItemValueArray(0,"relation").toString().replace(/,/g,"@"); var fullNames=getItemValueArray(0,"fullName").toString().replace(/,/g,"@"); - + var certIds=getItemValueArray(0,"certId").toString().replace(/,/g,"@"); + if(relations.length==0){ alert("请先选择数据!!!"); return; } - var result = RunJavaMethodTrans("com.tenwa.lease.flow.project.validate.IdentityVerification","doIdentityVerification","FlowUnid="+flowunid+",UserName="+username+",OrgName="+orgname+",relations="+relations+",fullNames="+fullNames+",customertype="+customertype+",SubjectId=<%=SubjectId%>"); + var result = RunJavaMethodTrans("com.tenwa.lease.flow.project.validate.alpha.identity.IdentityAlphaVerification","doIdentityVerification","FlowUnid="+flowunid+",UserName="+username+",OrgName="+orgname+",relations="+relations+",fullNames="+fullNames+",certIds="+certIds+",customertype="+customertype+",SubjectId=<%=SubjectId%>"); if(result == 'ERROR'){ alert("调用数据失败"); reloadSelf(); diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/IdentityAlphaVerification.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/IdentityAlphaVerification.java new file mode 100644 index 000000000..309728fed --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/IdentityAlphaVerification.java @@ -0,0 +1,327 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity; + +import com.amarsoft.are.jbo.*; +import com.tenwa.lease.flow.project.validate.NciicClient; +import com.tenwa.lease.flow.project.validate.SoapRequest; +import com.tenwa.lease.flow.project.validate.ValidatePropertiesUtil; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.EJQuestClient; +import jbo.app.tenwa.customer.CUSTOMER_FAMILY_TEMP; +import jbo.app.tenwa.customer.CUSTOMER_PERSON_TEMP; +import jbo.com.tenwa.lease.comm.LB_GUARANTEE_UNIT_TEMP; +import jbo.com.tenwa.lease.comm.LC_IDENTITY_CHECK_RESULT_TEMP; +import org.dom4j.Document; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sun.misc.BASE64Decoder; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 身份证校验类 + * @author 张磊 + * 2023年7月3日 下午2:18:21 + */ +public class IdentityAlphaVerification { + private static final Logger logger = LoggerFactory.getLogger(IdentityAlphaVerification.class); + private String FlowUnid; + private String UserName; + private String OrgName; + private String relations; + private String fullNames; + private String certIds; + private String customertype; + private String SubjectId; + + public String getCertIds() { + return certIds; + } + + public void setCertIds(String certIds) { + this.certIds = certIds; + } + + public String getFlowUnid() { + return FlowUnid; + } + + public void setFlowUnid(String flowUnid) { + FlowUnid = flowUnid; + } + + public String getUserName() { + return UserName; + } + + public void setUserName(String userName) { + UserName = userName; + } + + public String getOrgName() { + return OrgName; + } + + public void setOrgName(String orgName) { + OrgName = orgName; + } + + public String getRelations() { + return relations; + } + + public void setRelations(String relations) { + this.relations = relations; + } + + public String getFullNames() { + return fullNames; + } + + public void setFullNames(String fullNames) { + this.fullNames = fullNames; + } + + public String getCustomertype() { + return customertype; + } + + public void setCustomertype(String customertype) { + this.customertype = customertype; + } + + public String getSubjectId() { + return SubjectId; + } + + public void setSubjectId(String subjectId) { + SubjectId = subjectId; + } + + /** + * 保存校验结果 + * @param tx + * @param name + * @param certId + * @param httpRes + * @throws JBOException + */ + private void saveIdentityRes(JBOTransaction tx, String name, String certId, String httpRes) throws JBOException { + logger.info("IdentityAlphaVerificationSaveIdentityRes --【begin】--保存校验结果-:"+name); + BizObjectManager bom4 = JBOFactory.getBizObjectManager(LC_IDENTITY_CHECK_RESULT_TEMP.CLASS_NAME,tx); + BizObject resultObject = bom4.newObject(); + //向校验结果临时表存入数据 + resultObject.setAttributeValue("flowunid",FlowUnid); + resultObject.setAttributeValue("name",name); + resultObject.setAttributeValue("certid", certId); + resultObject.setAttributeValue("inputuserid",UserName); + resultObject.setAttributeValue("inputorgid", OrgName); + resultObject.setAttributeValue("inputtime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + String finalResult; + String[] httpResArr = httpRes.split(","); + if("0".equals(httpResArr[0])){ + logger.info("IdentityAlphaVerificationSaveIdentityRes --【info】--校验结果:一致-:"+name); + finalResult = "身份证校验结果:一致,姓名校验结果:一致"; + resultObject.setAttributeValue("result",finalResult); + }else{ + logger.info("IdentityAlphaVerificationSaveIdentityRes --【info】--校验错误原因为:"+httpResArr[1]); + finalResult = "错误原因为:"+httpResArr[1]; + } + resultObject.setAttributeValue("result", finalResult); + bom4.saveObject(resultObject); + logger.info("IdentityAlphaVerificationSaveIdentityRes --【end】--保存校验结果-:"+name); + } + + /** + * 实名认证 + * @param tx + * @return + */ + public String doIdentityVerification(JBOTransaction tx){ + String res = null; + logger.info("IdentityAlphaVerificationDoIdentityVerification --begin--" + UserName+"@"+OrgName+"@"+FlowUnid); + try { + // TODO: 2023-7-4 整理参数 + String[] fullNamesArr = fullNames.split("@"); + String[] certIdsArr = certIds.split("@"); + if(fullNamesArr.length != certIdsArr.length){ + logger.info("IdentityAlphaVerificationDoIdentityVerificationError --【end】--姓名和身份证信息数量不一致"); + return "姓名和身份证信息数量不一致!"; + } + // TODO: 2023-7-4 循环参数 + for(int i=0; i < fullNamesArr.length; i++){ + logger.info("IdentityAlphaVerificationDoIdentityVerification --【info】--begin-foreach:"+fullNamesArr[i]); + // TODO: 2023-7-5 判断是否已实名校验过 + BizObjectManager bom4 = JBOFactory.getBizObjectManager(LC_IDENTITY_CHECK_RESULT_TEMP.CLASS_NAME,tx); + BizObject queryResult = bom4.createQuery("select result from O where flowunid=:FLOWUNID and name = '"+fullNamesArr[i]+"'").setParameter("FLOWUNID",FlowUnid).getSingleResult(false); + if(null != queryResult){ + logger.info("IdentityAlphaVerificationDoIdentityVerification --【info】--已实名校验过:"+fullNamesArr[i]); + if(i == fullNamesArr.length-1){ + res += fullNamesArr[i]+ "实名校验成功"; + }else { + res += fullNamesArr[i]+ "实名校验成功@"; + } + continue; + } + // TODO: 2023-7-4 发起请求 +// String httpRes = EJQuestClient.httpIdentityUser(fullNamesArr[i], certIdsArr[i]); + String httpRes = "0,成功"; + // TODO: 2023-7-4 保存结果 + if(null == httpRes){ + if(i == fullNamesArr.length-1){ + res += fullNamesArr[i]+ "易捷云实名校验接口异常,请稍后再试!"; + }else { + res += fullNamesArr[i]+ "易捷云实名校验接口异常,请稍后再试!@"; + } + logger.info("IdentityAlphaVerificationDoIdentityVerificationError --【info】--易捷云实名校验接口异常,请稍后再试!:"+fullNamesArr[i]); + continue; + } + saveIdentityRes(tx, fullNamesArr[i], certIdsArr[i], httpRes); + logger.info("IdentityAlphaVerificationDoIdentityVerification --【info】--end-foreach:"+fullNamesArr[i]); + } + // TODO: 2023-7-4 整理返回结果 + } catch (Exception e) { + e.printStackTrace(); + logger.error("IdentityAlphaVerificationDoIdentityVerificationError 报错:", e); + res = "ERROR"; + } + logger.info("IdentityAlphaVerificationDoIdentityVerification --end--" + UserName+"@"+OrgName+"@"+FlowUnid); + return res; + } + public String doIdentityVerification2(JBOTransaction tx){ + logger.info("IdentityAlphaVerificationDoIdentityVerification --begin--" + UserName+"@"+OrgName+"@"+FlowUnid); + try { + BizObjectManager bom1 = JBOFactory.getBizObjectManager(CUSTOMER_PERSON_TEMP.CLASS_NAME,tx); + BizObjectManager bom2 = JBOFactory.getBizObjectManager(CUSTOMER_FAMILY_TEMP.CLASS_NAME, tx); + BizObjectManager bom3 = JBOFactory.getBizObjectManager(LB_GUARANTEE_UNIT_TEMP.CLASS_NAME, tx); + BizObjectManager bom4 = JBOFactory.getBizObjectManager(LC_IDENTITY_CHECK_RESULT_TEMP.CLASS_NAME,tx); + + String newfullName = fullNames.replace("@", "','"); + logger.info(newfullName); + BizObject queryResult = bom4.createQuery("select result from O where flowunid=:FLOWUNID and name in ('"+newfullName+"')").setParameter("FLOWUNID",FlowUnid).getSingleResult(false); + if(queryResult!=null){ + return "数据中已有身份证校验已校验过,不可重复执行!!!"; + }else{ + String[] NewRelations = relations.split("@"); + BizObject coborrowerResult = null; + @SuppressWarnings("unchecked") + List guarantorResultList = null ; + BizObject borrowerResult = null; + for(int i=0;i elements = rowElement.elements(); + String errormessage = elements.get(1).getText(); + return "验证失败,错误原因:"+errormessage; + //若根元素是ROWS则调用成功 + }else if("ROWS".equals(rootElement.getName())){ + @SuppressWarnings("unchecked") + List rowElement = rootElement.elements("ROW"); + for(int i=0;i inputElements = rowElement.get(i).element("INPUT").elements(); + String certid = inputElements.get(0).getText(); + String name = inputElements.get(1).getText(); + //向校验结果临时表存入数据 + resultObject.setAttributeValue("flowunid",FlowUnid); + resultObject.setAttributeValue("name",name); + resultObject.setAttributeValue("certid", certid); + resultObject.setAttributeValue("inputuserid",UserName); + resultObject.setAttributeValue("inputorgid", OrgName); + resultObject.setAttributeValue("inputtime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + //获取output中的所有item + @SuppressWarnings("unchecked") + List itemElements = rowElement.get(i).element("OUTPUT").elements("ITEM"); + //获取第一个item + @SuppressWarnings("unchecked") + List outputCertIdElements= itemElements.get(0).elements(); + //获取第二个item + @SuppressWarnings("unchecked") + List outputNameElements= itemElements.get(1).elements(); + //判断第一个item中的第一个标签元素的名字 + if("gmsfhm".equals(outputCertIdElements.get(0).getName())){ + String certIdResult = outputCertIdElements.get(1).getText(); + String nameResult = outputNameElements.get(1).getText(); + finalResult = "身份证校验结果:"+certIdResult+",姓名校验结果:"+nameResult; + resultObject.setAttributeValue("result",finalResult); + }else if("errormesage".equals(outputCertIdElements.get(0).getName())){ + String errorResult = outputCertIdElements.get(0).getText(); + finalResult = "错误原因为:"+errorResult; + resultObject.setAttributeValue("result", finalResult); + } + bom4.saveObject(resultObject); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + return "ERROR"; + } + return "SUCCESS"; + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/EJQuestClient.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/EJQuestClient.java new file mode 100644 index 000000000..579b40f9d --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/EJQuestClient.java @@ -0,0 +1,204 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy; + +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.GlobalReqBizPackage; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.GlobalVo; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.apply.ApplyRequestBizData; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.apply.ApplyResponseBizData; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.verification.VerificationRequestBizData; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.verification.VerificationResponseBizData; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.config.Config; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.config.EJYEnums; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.config.VerificationConfig; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils.EncodesUtil; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils.HttpUtil; +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils.JSONUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 易捷云平台对接内容汇总 + * 统一申请接口 + * 校验接口 + */ +public class EJQuestClient { + private static final Logger logger = LoggerFactory.getLogger(EJQuestClient.class); + + /** + * 实名认证单个用户 + * @return + */ + public static String httpIdentityUser(String name, String idCard){ + String applyRes = createApply(); + if(null == applyRes){ + return null; + } + String[] applyResArr = applyRes.split(","); + return applyIdentity(name, idCard, applyResArr[0], applyResArr[1]); + } + + /** + * 统一申请接口调用 + * @return + * @throws Exception + */ + private static String createApply() { + //1、组装赋码申请数据 + GlobalReqBizPackage createApply = new GlobalReqBizPackage<>(); + // TODO: 2023-7-4 统一申请接口的参数 业务类型 与平台确认 + createApply.setBizType(6000); + // TODO: 2023-7-4 平台分配的机构代号 与平台确认 + createApply.setOrgCode("机构代号"); + createApply.setBizData(new ApplyRequestBizData()); + // TODO: 2023-7-4 统一申请接口的参数 认证模式 与平台确认 + createApply.getBizData().setAuthMode("0x40"); + String createApplyJson = JSONUtil.toJson(createApply); //转换成json格式 + + //2、签名 + byte[] signArray = new byte[0]; + try { + signArray = Config.signService.sign(Config.PRIVATE_KEY, createApplyJson.getBytes()); + } catch (Exception e) { + e.printStackTrace(); + logger.error("EJQuestClientErrorCreateApply 统一申请: 签名报错:", e); + return null; + } + String signString = EncodesUtil.encodeBase64(signArray); + + //3、请求包组装 + GlobalVo globalVo = new GlobalVo(); + globalVo.setSign(signString); + globalVo.setBizPackage(createApplyJson); + String createApplyPackage = JSONUtil.toJson(globalVo); + logger.info("EJQuestClientINFO 统一申请: 统一申请: " + createApplyPackage); + //4、发送请求 + String createApplyResult = null; + try { + createApplyResult = HttpUtil.doPost(Config.URL_APPLY, createApplyPackage); + logger.info("EJQuestClientINFO 统一申请: 统一申请申请结果: " + createApplyResult); + } catch (Exception e) { + e.printStackTrace(); + logger.error("EJQuestClientErrorCreateApply 统一申请: 发送请求报错:", e); + return null; + } + + //5、解析返回结果 + GlobalVo createApplyResultJson = JSONUtil.json2Object(createApplyResult, GlobalVo.class); + ApplyResponseBizData applyResponseBizData = JSONUtil.json2Object(createApplyResultJson.getBizPackage(), ApplyResponseBizData.class); + //对返回结果进行验签 + byte[] signByte = EncodesUtil.decodeBase64(createApplyResultJson.getSign()); + try { + if (!Config.signService.verifySign(Config.PUBLIC_SIGN_KEY, signByte, createApplyResultJson.getBizPackage().getBytes())) { + logger.info("--------生码请求请求成功,对返回结果验签未通过"); + logger.error("EJQuestClientErrorCreateApply 统一申请: 生码请求请求成功,对返回结果验签未通过"); + return null; + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("EJQuestClientErrorCreateApply 统一申请: 对返回结果进行验签报错:", e); + return null; + } + +// 如果返回结果为0表示成功 + if ("0".equals(applyResponseBizData.getResultCode())) { + + //保存流水号、随机数,后续请求使用 + String bsn = applyResponseBizData.getBizData().getBsn(); + String randomNumber = applyResponseBizData.getBizData().getRandomNumber(); + logger.info("EJQuestClientINFO 统一申请: bsn = " + bsn); + logger.info("EJQuestClientINFO 统一申请: randomNumber = " + randomNumber); + return bsn+","+randomNumber; + } else { + logger.error("EJQuestClientErrorCreateApply 统一申请: 未成功申请请求"); + return null; + } + + } + + /** + * 身份核验接口调用 + * @param name + * @param idCard + * @param bsn + * @param randomNumber + * @return + * @throws Exception + */ + private static String applyIdentity(String name, String idCard, String bsn, String randomNumber) { + GlobalReqBizPackage req = new GlobalReqBizPackage<>(); + // TODO: 2023-7-4 统一申请接口的参数 业务类型 与平台确认 + req.setBizType(6000); + // TODO: 2023-7-4 平台分配的机构代号 与平台确认 + req.setOrgCode("机构代号"); + req.setBsn(bsn); + + req.setBizData(new VerificationRequestBizData()); + // TODO: 2023-7-4 统一申请接口的参数 认证模式 与平台确认 + req.getBizData().setAuthMode("0x40"); + VerificationRequestBizData.AuthApplyRetainData authApplyRetainData = new VerificationRequestBizData.AuthApplyRetainData(); + authApplyRetainData.setName(name); + authApplyRetainData.setIdNo(idCard); + String strAuthApplyRetainData = JSONUtil.toJson(authApplyRetainData); + byte[] res = Config.signService.encryptAES(Config.PUBLIC_ENCRYPT_KEY, strAuthApplyRetainData.getBytes()); + req.getBizData().setAuthApplyRetainData(EncodesUtil.encodeBase64(res)); + String createApplyJson = JSONUtil.toJson(req); //转换成json格式 + + //2、签名 + byte[] signArray = new byte[0]; + try { + signArray = Config.signService.sign(Config.PRIVATE_KEY, createApplyJson.getBytes()); + } catch (Exception e) { + e.printStackTrace(); + logger.error("EJQuestClientErrorApplyIdentity 身份校验: 签名报错:", e); + return null; + + } + String signString = EncodesUtil.encodeBase64(signArray); + + //3、请求包组装 + GlobalVo globalVo = new GlobalVo(); + globalVo.setSign(signString); + globalVo.setBizPackage(createApplyJson); + String createApplyPackage = JSONUtil.toJson(globalVo); + + //4、发送请求 + String createApplyResult; + try { + createApplyResult = HttpUtil.doPost(Config.URL_VERIFICATION, createApplyPackage); + logger.info(" 核验请求响应: " + createApplyResult); + } catch (Exception e) { + e.printStackTrace(); + logger.error("EJQuestClientErrorApplyIdentity 身份校验: 发送请求报错:", e); + return null; + } + GlobalVo createApplyResultJson = JSONUtil.json2Object(createApplyResult, GlobalVo.class); + VerificationResponseBizData applyResponse = JSONUtil.json2Object(createApplyResultJson.getBizPackage(), VerificationResponseBizData.class); + //对返回结果进行验签 + byte[] signByte = EncodesUtil.decodeBase64(createApplyResultJson.getSign()); + try { + if (!Config.signService.verifySign(Config.PUBLIC_SIGN_KEY, signByte, createApplyResultJson.getBizPackage().getBytes())) { + logger.info("--------生码请求请求成功,对返回结果验签未通过"); + logger.error("EJQuestClientErrorApplyIdentity 身份校验: 生码请求请求成功,对返回结果验签未通过"); + return null; + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("EJQuestClientErrorApplyIdentity 身份校验: 对返回结果验签报错:", e); + return null; + } + //如果返回结果为0表示成功 + if ("0".equals(applyResponse.getResultCode())) { + logger.info(" bId=" + applyResponse.getBizData().getBId()); + logger.info(" photoCompareScore=" + applyResponse.getBizData().getPhotoCompareScore()); + return "0"+","+applyResponse.getBizData().getBId(); + } else { + String errorDesc = EJYEnums.ResCodeEnum.findDesc(applyResponse.getResultCode()); + if(null == errorDesc){ + errorDesc = "易捷云平台异常状态:" + applyResponse.getResultCode(); + } + logger.info("============= 未成功核验请求 ==========="); + logger.error("EJQuestClientErrorApplyIdentity 身份校验: 未成功核验请求"); + return "1"+","+errorDesc; + } + } + +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/GlobalReqBizPackage.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/GlobalReqBizPackage.java new file mode 100644 index 000000000..9a9c35641 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/GlobalReqBizPackage.java @@ -0,0 +1,49 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean; + + +/** + * @author Ivan on 2019/11/15. + * @version 1.0 + */ +public class GlobalReqBizPackage { + + private Integer bizType; + + private String orgCode; + + private String bsn; + + private T bizData; + + public Integer getBizType() { + return bizType; + } + + public void setBizType(Integer bizType) { + this.bizType = bizType; + } + + public String getOrgCode() { + return orgCode; + } + + public void setOrgCode(String orgCode) { + this.orgCode = orgCode; + } + + public String getBsn() { + return bsn; + } + + public void setBsn(String bsn) { + this.bsn = bsn; + } + + public T getBizData() { + return bizData; + } + + public void setBizData(T bizData) { + this.bizData = bizData; + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/GlobalVo.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/GlobalVo.java new file mode 100644 index 000000000..e56991c27 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/GlobalVo.java @@ -0,0 +1,35 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean; + +/** + * @author Ivan on 2019/11/15. + * @version 1.0 + */ +public class GlobalVo { + + private String bizPackage; + + private String sign; + + public GlobalVo(String bizPackage, String sign) { + this.bizPackage = bizPackage; + this.sign = sign; + } + public GlobalVo() { + + } + public String getBizPackage() { + return bizPackage; + } + + public void setBizPackage(String bizPackage) { + this.bizPackage = bizPackage; + } + + public String getSign() { + return sign; + } + + public void setSign(String sign) { + this.sign = sign; + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/apply/ApplyRequestBizData.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/apply/ApplyRequestBizData.java new file mode 100644 index 000000000..977915ae2 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/apply/ApplyRequestBizData.java @@ -0,0 +1,14 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.apply; + + +public class ApplyRequestBizData { + private String authMode; + + public String getAuthMode() { + return authMode; + } + + public void setAuthMode(String authMode) { + this.authMode = authMode; + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/apply/ApplyResponseBizData.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/apply/ApplyResponseBizData.java new file mode 100644 index 000000000..4826bc4b2 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/apply/ApplyResponseBizData.java @@ -0,0 +1,44 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.apply; + + +public class ApplyResponseBizData { + private BizData bizData; + private String resultCode; + + public BizData getBizData() { + return bizData; + } + + public void setBizData(BizData bizData) { + this.bizData = bizData; + } + + public String getResultCode() { + return resultCode; + } + + public void setResultCode(String resultCode) { + this.resultCode = resultCode; + } + + public class BizData { + private String bsn; + private String randomNumber; + + public String getBsn() { + return bsn; + } + + public void setBsn(String bsn) { + this.bsn = bsn; + } + + public String getRandomNumber() { + return randomNumber; + } + + public void setRandomNumber(String randomNumber) { + this.randomNumber = randomNumber; + } + } +} \ No newline at end of file diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/verification/VerificationRequestBizData.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/verification/VerificationRequestBizData.java new file mode 100644 index 000000000..d04820e00 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/verification/VerificationRequestBizData.java @@ -0,0 +1,82 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.verification; + +public class VerificationRequestBizData { + private String authMode; + + private String photoData; + + private String authApplyRetainData; + + private String photoData2; + + public String getAuthMode() { + return authMode; + } + + public void setAuthMode(String authMode) { + this.authMode = authMode; + } + + public String getPhotoData() { + return photoData; + } + + public void setPhotoData(String photoData) { + this.photoData = photoData; + } + + public String getAuthApplyRetainData() { + return authApplyRetainData; + } + + public void setAuthApplyRetainData(String authApplyRetainData) { + this.authApplyRetainData = authApplyRetainData; + } + + public String getPhotoData2() { + return photoData2; + } + + public void setPhotoData2(String photoData2) { + this.photoData2 = photoData2; + } + + public static class AuthApplyRetainData { + private String name; + private String idNo; + private String idIssueDate; + private String idExpireDate; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIdNo() { + return idNo; + } + + public void setIdNo(String idNo) { + this.idNo = idNo; + } + + public String getIdIssueDate() { + return idIssueDate; + } + + public void setIdIssueDate(String idIssueDate) { + this.idIssueDate = idIssueDate; + } + + public String getIdExpireDate() { + return idExpireDate; + } + + public void setIdExpireDate(String idExpireDate) { + this.idExpireDate = idExpireDate; + } + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/verification/VerificationResponseBizData.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/verification/VerificationResponseBizData.java new file mode 100644 index 000000000..0baa53e36 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/bean/verification/VerificationResponseBizData.java @@ -0,0 +1,47 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.bean.verification; + + + + +public class VerificationResponseBizData { + private BizData bizData; + private String resultCode; + + public BizData getBizData() { + return bizData; + } + + public void setBizData(BizData bizData) { + this.bizData = bizData; + } + + public String getResultCode() { + return resultCode; + } + + public void setResultCode(String resultCode) { + this.resultCode = resultCode; + } + + + public class BizData { + private String bId; + private String photoCompareScore; + + public String getBId() { + return bId; + } + + public void setBId(String bId) { + this.bId = bId; + } + + public String getPhotoCompareScore() { + return photoCompareScore; + } + + public void setPhotoCompareScore(String photoCompareScore) { + this.photoCompareScore = photoCompareScore; + } + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/Config.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/Config.java new file mode 100644 index 000000000..886bebf5b --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/Config.java @@ -0,0 +1,62 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.config; + +import com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils.SignService; + +import java.util.HashMap; +import java.util.Map; + +public class Config { + + + public static Map bizTypeMode = new HashMap<>(); + + static { + bizTypeMode.put(BizType.X6000, "6000-韬唤鏍搁獙"); + } + + public static class BizType { + //璋冪敤鐢宠鎺ュ彛 + public static final Integer X1000 = 1000; + //韬唤鏍搁獙 + public static final Integer X6000 = 6000; + } + + + /** + * 绛惧悕宸ュ叿 + */ + public static SignService signService = new SignService(); + + public static String domain = "api.easyctid.cn"; + + public static String URL_APPLY = "http://" + domain + "/v1/apply"; + public static String URL_VERIFICATION = "http://" + domain + "/ctid/v1/verification"; + + + /** + * 浠ヤ笅涓変釜涓鸿祴鐮侀獙鐮佽繃绋嬩腑鐨勪笂涓嬫枃鍙橀噺 + */ + public static String bsn; + public static String randomNumber; + + + public static String ORGCODE = ""; + public static String name = ""; + public static String idNo = ""; + public static String idExpireDate = ""; + public static String idIssueDate = ""; + + //鐢ㄦ埛绛惧悕绉侀挜 + public static String PRIVATE_KEY = ""; + + //骞冲彴楠岀鍏挜 + public static String PUBLIC_SIGN_KEY = ""; + //骞冲彴鍔犲瘑鍏挜 + public static String PUBLIC_ENCRYPT_KEY = ""; + + // + public static String photoData = ""; + // + public static String photoData2 = ""; + +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/EJYEnums.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/EJYEnums.java new file mode 100644 index 000000000..68e31b6a1 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/EJYEnums.java @@ -0,0 +1,77 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.config; + +import com.tenwa.app.manage.qiyuesuo.v2.ContractSignEnums; + +/** + * 易捷云平台的枚举 + */ +public class EJYEnums { + /** + * 签署类型 + * + */ + public enum ResCodeEnum{ + + SUCCESS("0", "成功"), + ERR_I120000("I120000", "网关:内部异常、访问后台服务失败等 网关:内部异常、访问后台服务失败等 ,对应 http 状态码 状态码 : 404 、 500 、503"), + ERR_I120001("I120001", "网关:层系统繁忙(过载保护),对应http状态码: 503"), + ERR_I110000("I110000","网关:无法解析的请求、缺少键字段,对应http状态码: 400"), + ERR_I110001("I110001","网关:身份获取失败、验签等,对应 网关:身份获取失败、验签等,对应 网关:身份获取失败、验签等,对应http状态码: 401"), + ERR_I110002("I110002","网关:应用无权限 网关:应用无权限 网关:应用无权限 对应 http 状态码: 状态码: 403"), + ERR_I110003("I110003","网关:服务调用次数上限,对应 http http 状态码: 状态码: 403"), + ERR_100000("100000","系统异常,请联管理员!"), + ERR_100001("100001","CTID 系统异常 系统异常 , 请联系管理员! 请联系管理员!"), + ERR_100002("100002","授权流量达到上限"), + ERR_100003("100003","授权用户已达上限"), + ERR_100004("100004","授权文件更新失败"), + ERR_100005("100005","请求头校验失败"), + ERR_110001("110001","包格式错误"), + ERR_110002("110002","参数错误"), + ERR_110003("110003","业务流水号错误或者失效"), + ERR_110004("110004","网证下载参数错误"), + ERR_110005("110005","数据解密失败"), + ERR_110006("110006","申请、请求两包随机数不匹配"), + ERR_110007("110007","数据字段值非法"), + ERR_110008("110008","签名验失败"), + ERR_200001("200001","身份信息无效或不匹配,请检查身份信息是否正确或使用具有"), + ERR_200002("200002","身份信息格式不正确或匹配 ,请检查身份信息"), + ERR_200003("200003","证件已过期"), + ERR_210001("210001","人 像非同一人"), + ERR_210002("210002","人像疑似 ,请重新拍照或传入合格片"), + ERR_210003("210003","无人像信息 ,请检查身份信息是否正确或使用"), + ERR_210004("210004","图像格式不支持"), + ERR_210005("210005","待比对图像建模失败"), + ERR_210006("210006","现场照片质量不合格"), + ERR_210007("210007","活体检测控件版本过期"), + ERR_210008("210008","活体检测数据校验失败"), + ERR_210009("210009","现场照片小于5K,请重新拍照或传入合格片"), + ERR_210010("210010","证件照片小于5k, 建议使用具有NFC功能的手机下载CTID官方APP开通网证。"); + + private String type; //流程编号 + private String desc; //描述 + private ResCodeEnum(String type, String desc){ + + this.type=type; + this.desc=desc; + } + + + public String getType() { + return type; + } + + public String getDesc() { + return desc; + } + + public static String findDesc(String code){ + for(ResCodeEnum e : ResCodeEnum.values()){ + if(code.equals(e.getType())){ + return e.getDesc(); + } + } + return null; + } + + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/VerificationConfig.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/VerificationConfig.java new file mode 100644 index 000000000..572febdd7 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/config/VerificationConfig.java @@ -0,0 +1,42 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.config; + +import java.util.HashMap; +import java.util.Map; + +public class VerificationConfig { + public static Map verificationMode = new HashMap<>(); + + static { + verificationMode.put(VerificationMode.X70, "1"); + verificationMode.put(VerificationMode.X69, "1"); + verificationMode.put(VerificationMode.X68, "1"); + verificationMode.put(VerificationMode.X65, "1"); + verificationMode.put(VerificationMode.X66, "1"); + verificationMode.put(VerificationMode.X10, "1"); + verificationMode.put(VerificationMode.X12, "1"); + verificationMode.put(VerificationMode.X40, "1"); + verificationMode.put(VerificationMode.X42, "1"); + verificationMode.put(VerificationMode.X18, "1"); + } + + public static class VerificationMode { + public static final String X70 = "0x70"; + public static final String X69 = "0x69"; + //2椤逛俊鎭(杩擯ID) + public static final String X68 = "0x68"; + // + public static final String X65 = "0x65"; + // + public static final String X66 = "0x66"; + //4椤逛俊鎭 + public static final String X10 = "0x10"; + //浜哄儚+ 4椤逛俊鎭 + public static final String X12 = "0x12"; + //2椤逛俊鎭 + public static final String X40 = "0x40"; + //浜哄儚+2椤逛俊鎭 + public static final String X42 = "0x42"; + //4椤逛俊鎭繑璇佷欢鐘舵 + public static final String X18 = "0x18"; + } +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/AESCryptService.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/AESCryptService.java new file mode 100644 index 000000000..d08016abf --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/AESCryptService.java @@ -0,0 +1,94 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils; + +import org.apache.commons.lang3.RandomStringUtils; + +import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.*; + + +public class AESCryptService { + public static final int AES_KEY_LENGTH = 128; + public static final int AES_IV_SIZE = 16; + + + private static final String ALGORITHM_KEY = "AES"; + private static final String ALGORITHM_CIPHER = "AES/CBC/PKCS5Padding"; + + private static ThreadLocal localCipher = new ThreadLocal<>(); + + private KeyGenerator keyGenerator; + + public AESCryptService() { + try { + keyGenerator = KeyGenerator.getInstance(ALGORITHM_KEY); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("娌℃湁" + ALGORITHM_KEY + "鐩稿叧鐨勫疄鐜"); + } + keyGenerator.init(AES_KEY_LENGTH, new SecureRandom()); + } + + + public byte[] encrypt(Key key, IvParameterSpec iv, byte[] content) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException { + return doCrypt(key, Cipher.ENCRYPT_MODE, iv, content, 0, content.length); + } + + public byte[] encrypt(Key key, IvParameterSpec iv, byte[] content, int start, int length) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException { + return doCrypt(key, Cipher.ENCRYPT_MODE, iv, content, start, length); + } + + public byte[] deCrypt(Key key, IvParameterSpec iv, byte[] content) throws BadPaddingException, InvalidKeyException, IllegalBlockSizeException { + return doCrypt(key, Cipher.DECRYPT_MODE, iv, content, 0, content.length); + } + + public byte[] deCrypt(Key key, IvParameterSpec iv, byte[] content, int start, int length) throws BadPaddingException, InvalidKeyException, IllegalBlockSizeException { + return doCrypt(key, Cipher.DECRYPT_MODE, iv, content, start, length); + } + + public SecretKey parseKey(byte[] bytes, int start, int length) { + return new SecretKeySpec(bytes, start, length, ALGORITHM_KEY); + } + + public IvParameterSpec parseIv(byte[] bytes, int start, int length) { + return new IvParameterSpec(bytes, start, length); + } + + public SecretKey randomKey() { + return keyGenerator.generateKey(); + } + + public IvParameterSpec randomIv() { + return parseIv(randomString(AES_IV_SIZE).getBytes(), 0, AES_IV_SIZE); + } + + + public static String randomString(int length) { + return RandomStringUtils.random(length, "1234567890abcdefABCDEF-/=+_"); + } + + private byte[] doCrypt(Key key, int mode, IvParameterSpec iv, byte[] content, int start, int length) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException { + Cipher cipher = getCipher(); + try { + cipher.init(mode, key, iv); + } catch (InvalidAlgorithmParameterException e) { + //姝e父鎯呭喌涓嶄細鍑虹幇璇ュ紓甯 + throw new RuntimeException("un expect algorithm-parameter", e); + } + return cipher.doFinal(content, start, length); + } + + private Cipher getCipher() { + Cipher cipher = localCipher.get(); + if (null == cipher) { + try { + cipher = Cipher.getInstance(ALGORITHM_CIPHER); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new RuntimeException("娌℃湁鎵惧埌'" + ALGORITHM_CIPHER + "'鐨勫疄鐜", e); + } + localCipher.set(cipher); + } + return cipher; + } + +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/EncodesUtil.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/EncodesUtil.java new file mode 100644 index 000000000..bf932cd18 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/EncodesUtil.java @@ -0,0 +1,21 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils; + +import org.apache.commons.codec.binary.Base64; + +public class EncodesUtil { + + /** + * Base64缂栫爜. + */ + public static String encodeBase64(byte[] input) { + return Base64.encodeBase64String(input); + } + + /** + * Base64瑙g爜. + */ + public static byte[] decodeBase64(String input) { + return Base64.decodeBase64(input); + } + +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/HttpUtil.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/HttpUtil.java new file mode 100644 index 000000000..3e65674ba --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/HttpUtil.java @@ -0,0 +1,36 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils; + + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + + +public class HttpUtil { + + public static String doPost(String uri, String param) throws IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + + HttpPost post = new HttpPost(uri); + post.setHeader("Content-Type", "application/json"); + StringEntity entity = new StringEntity(param, StandardCharsets.UTF_8); + post.setEntity(entity); + + HttpResponse response = httpClient.execute(post); + +// int statusCode = response.getStatusLine().getStatusCode(); +// if (statusCode != 200) { +// throw new RuntimeException("http璇锋眰寮傚父" + statusCode); +// } + + return EntityUtils.toString(response.getEntity(), "UTF-8"); + } + + +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/JSONUtil.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/JSONUtil.java new file mode 100644 index 000000000..8cf6520a7 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/JSONUtil.java @@ -0,0 +1,52 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import java.util.Map; + +public class JSONUtil { + + /** + * 灏咼SON瀛楃涓茶浆鎹负Java瀵硅薄. + * + * @param jsonStr + * @param clazz 鐩爣瀵硅薄鐨凜lass绫. + * @return Java瀵硅薄 + */ + @SuppressWarnings("unchecked") + public static T json2Object(String jsonStr, Class clazz) { + try { + return (T) JSON.parseObject(jsonStr, clazz); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 灏咼ava瀵硅薄杞崲涓簀son瀛楃涓. + * 绂佺敤寰幆寮曠敤妫娴. + * + * @param obj + * @return json瀛楃涓. + */ + public static String toJson(Object obj) { + try { + return JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static Map json2Map(String jsonString) { + try { + return JSON.parseObject(jsonString, + new TypeReference>() { + }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/KeyStore.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/KeyStore.java new file mode 100644 index 000000000..9e253e8f0 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/KeyStore.java @@ -0,0 +1,32 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils; + +import java.security.Key; + +public class KeyStore { + + public KeyStore(Key key, int keyType) { + this.key = key; + byte[] src = key.getEncoded(); + base64Src = EncodesUtil.encodeBase64(src); + this.mode = keyType; + } + + private String base64Src; + + private Key key; + + private int mode; + + public String getBase64Src() { + return base64Src; + } + + public Key getKey() { + return key; + } + + public int getMode() { + return mode; + } + +} diff --git a/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/SignService.java b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/SignService.java new file mode 100644 index 000000000..8b0e20970 --- /dev/null +++ b/src_tenwa/com/tenwa/lease/flow/project/validate/alpha/identity/ejy/utils/SignService.java @@ -0,0 +1,174 @@ +package com.tenwa.lease.flow.project.validate.alpha.identity.ejy.utils; + + +import com.sun.crypto.provider.SunJCE; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import java.io.ByteArrayOutputStream; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +public class SignService { + + private static final String ALGORITHM = "RSA"; + private static final byte[] VER = EncodesUtil.decodeBase64("Gdp0WDe1XR/BFs9qHai3Gg=="); + private static final KeyFactory keyFactory; + private AESCryptService aesService = new AESCryptService(); + + private static ThreadLocal cipherLocal = new ThreadLocal<>(); + static { + try { + keyFactory = KeyFactory.getInstance(ALGORITHM); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("no ALGORITHM for '" + ALGORITHM + "'"); + } + } + + + public byte[] encryptAES(String pubKey, byte[] plaintext) { + + //AES + SecretKey aesKey = aesService.randomKey(); + IvParameterSpec iv = aesService.randomIv(); + byte[] enContent = new byte[0]; + try { + enContent = aesService.encrypt(aesKey, iv, plaintext); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("AES鍔犲瘑澶辫触"); + } catch (InvalidKeyException e) { + System.out.println("AES绉橀挜涓嶅彲鐢"); + } + + try { + //RSA + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + bout.write(aesKey.getEncoded()); + bout.write(iv.getIV()); + bout.write(VER); //鐗堟湰淇℃伅锛屽鍔犺В瀵嗘棤浠讳綍褰卞搷 + byte[] enDes = encryptKey(pubKey, bout.toByteArray()); + + //parse + bout.reset(); + bout.write(enDes); + bout.write(enContent); + return bout.toByteArray(); + } catch (Exception e) { + throw new RuntimeException("鍔犲瘑鍙戠敓閿欒", e); + } + } + + + public byte[] encryptKey(String pubKey, byte[] content) throws InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException { + return encrypt(pubKey, content, 0, content.length); + } + + public byte[] encrypt(String pubKey, byte[] content, int start, int length) throws InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException { + return doCrypt(pubKey, Cipher.ENCRYPT_MODE, content, start, length); + } + + private byte[] doCrypt(String key, int mode, byte[] content, int start, int length) throws InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException { + KeyStore store = prepareKeyStore(key, mode); + Cipher cipher = getCipher(store); + return cipher.doFinal(content, start, length); + } + + protected Cipher getCipher(KeyStore store) { + try { + Cipher cipher = cipherLocal.get(); + if (null == cipher) { + cipher = Cipher.getInstance(SYSTEM_CIPHER_ALGORITHM, new SunJCE()); + cipherLocal.set(cipher); + } + cipher.init(store.getMode(), store.getKey()); + return cipher; + } catch (Exception e) { + throw new RuntimeException("娌℃湁鎵惧埌" + SYSTEM_CIPHER_ALGORITHM + "鐨勫姞瀵嗙畻娉", e); + } + } + + public static RSAPublicKey getRSAPublicKey(byte[] pubKeyData) throws InvalidKeySpecException { + X509EncodedKeySpec spec = new X509EncodedKeySpec(pubKeyData); + return (RSAPublicKey) keyFactory.generatePublic(spec); + } + + public static RSAPrivateKey getRSAPrivateKey(byte[] priKeyData) throws InvalidKeySpecException { + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(priKeyData); + return (RSAPrivateKey) keyFactory.generatePrivate(spec); + } + + + public boolean verifySign(String pubKey, byte[] sign, byte[] content) throws Exception { + return verifySign(pubKey, sign, content, 0, content.length); + } + + public byte[] sign(String priKey, byte[] content) throws Exception { + return sign(priKey, content, 0, content.length); + } + + public boolean verifySign(String pubKey, byte[] sign, byte[] content, int start, int length) throws InvalidKeySpecException, SignatureException { + KeyStore store = prepareKeyStore(pubKey, Cipher.PUBLIC_KEY); + Signature signature = getSignature(store); + signature.update(content, start, length); + return signature.verify(sign); + } + + + private static final String SYSTEM_CIPHER_ALGORITHM = "RSA"; + private static final String SYSTEM_SIGNATURE_ALGORITHM = "SHA256withRSA"; + + private Map priKeyMap = new HashMap<>(512); + private Map pubKeyMap = new HashMap<>(512); + + + public byte[] sign(String priKey, byte[] content, int start, int length) throws InvalidKeySpecException, SignatureException { + KeyStore store = prepareKeyStore(priKey, Cipher.PRIVATE_KEY); + Signature signature = getSignature(store); + signature.update(content, start, length); + return signature.sign(); + } + + protected Signature getSignature(KeyStore store) { + try { + Signature signature = Signature.getInstance(SYSTEM_SIGNATURE_ALGORITHM); + if (store.getMode() == Cipher.PRIVATE_KEY) { + signature.initSign((PrivateKey) store.getKey()); + } else if (store.getMode() == Cipher.PUBLIC_KEY) { + signature.initVerify((PublicKey) store.getKey()); + } + return signature; + } catch (Exception e) { + throw new RuntimeException("娌℃湁鎵惧埌" + SYSTEM_SIGNATURE_ALGORITHM + "鐨勭鍚嶇畻娉", e); + } + } + + private KeyStore prepareKeyStore(String key, int mode) throws InvalidKeySpecException { + Map storeMap = mode == Cipher.PUBLIC_KEY ? pubKeyMap : priKeyMap; + KeyStore store = storeMap.get(key); + + if (null == store) { + byte[] keyByte = EncodesUtil.decodeBase64(key); + Key rsaKey; + if (mode == Cipher.ENCRYPT_MODE) { + rsaKey = getRSAPublicKey(keyByte); + } else { + rsaKey = getRSAPrivateKey(keyByte); + } + + store = new KeyStore(rsaKey, mode); + storeMap.put(key, store); + } + + return store; + } + +}