mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
秘钥管理改造
This commit is contained in:
@@ -4,3 +4,4 @@
|
|||||||
- 运行`SopAdminServerApplication.java`
|
- 运行`SopAdminServerApplication.java`
|
||||||
- 访问:`http://localhost:8082`
|
- 访问:`http://localhost:8082`
|
||||||
|
|
||||||
|
登录账号:admin/123456
|
||||||
|
@@ -8,29 +8,32 @@ import com.gitee.easyopen.doc.annotation.ApiDoc;
|
|||||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||||
import com.gitee.easyopen.util.CopyUtil;
|
import com.gitee.easyopen.util.CopyUtil;
|
||||||
import com.gitee.easyopen.util.KeyStore;
|
|
||||||
import com.gitee.easyopen.util.RSAUtil;
|
|
||||||
import com.gitee.fastmybatis.core.PageInfo;
|
import com.gitee.fastmybatis.core.PageInfo;
|
||||||
import com.gitee.fastmybatis.core.query.Query;
|
import com.gitee.fastmybatis.core.query.Query;
|
||||||
import com.gitee.fastmybatis.core.util.MapperUtil;
|
import com.gitee.fastmybatis.core.util.MapperUtil;
|
||||||
import com.gitee.sop.adminserver.api.IdParam;
|
import com.gitee.sop.adminserver.api.IdParam;
|
||||||
import com.gitee.sop.adminserver.api.isv.param.IsvInfoForm;
|
|
||||||
import com.gitee.sop.adminserver.api.isv.param.IsvInfoFormAdd;
|
import com.gitee.sop.adminserver.api.isv.param.IsvInfoFormAdd;
|
||||||
import com.gitee.sop.adminserver.api.isv.param.IsvInfoFormUpdate;
|
import com.gitee.sop.adminserver.api.isv.param.IsvInfoFormUpdate;
|
||||||
|
import com.gitee.sop.adminserver.api.isv.param.IsvKeysFormUpdate;
|
||||||
|
import com.gitee.sop.adminserver.api.isv.param.IsvKeysGen;
|
||||||
import com.gitee.sop.adminserver.api.isv.param.IsvPageParam;
|
import com.gitee.sop.adminserver.api.isv.param.IsvPageParam;
|
||||||
import com.gitee.sop.adminserver.api.isv.result.IsvFormVO;
|
import com.gitee.sop.adminserver.api.isv.result.IsvDetailDTO;
|
||||||
import com.gitee.sop.adminserver.api.isv.result.IsvVO;
|
import com.gitee.sop.adminserver.api.isv.result.IsvInfoVO;
|
||||||
|
import com.gitee.sop.adminserver.api.isv.result.IsvKeysGenVO;
|
||||||
|
import com.gitee.sop.adminserver.api.isv.result.IsvKeysVO;
|
||||||
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
||||||
import com.gitee.sop.adminserver.bean.ChannelMsg;
|
import com.gitee.sop.adminserver.bean.ChannelMsg;
|
||||||
import com.gitee.sop.adminserver.bean.ZookeeperContext;
|
import com.gitee.sop.adminserver.bean.ZookeeperContext;
|
||||||
import com.gitee.sop.adminserver.common.BizException;
|
import com.gitee.sop.adminserver.common.BizException;
|
||||||
import com.gitee.sop.adminserver.common.IdGen;
|
import com.gitee.sop.adminserver.common.IdGen;
|
||||||
import com.gitee.sop.adminserver.common.ZookeeperOperationException;
|
import com.gitee.sop.adminserver.common.RSATool;
|
||||||
import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException;
|
import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException;
|
||||||
import com.gitee.sop.adminserver.entity.IsvInfo;
|
import com.gitee.sop.adminserver.entity.IsvInfo;
|
||||||
|
import com.gitee.sop.adminserver.entity.IsvKeys;
|
||||||
import com.gitee.sop.adminserver.entity.PermIsvRole;
|
import com.gitee.sop.adminserver.entity.PermIsvRole;
|
||||||
import com.gitee.sop.adminserver.entity.PermRole;
|
import com.gitee.sop.adminserver.entity.PermRole;
|
||||||
import com.gitee.sop.adminserver.mapper.IsvInfoMapper;
|
import com.gitee.sop.adminserver.mapper.IsvInfoMapper;
|
||||||
|
import com.gitee.sop.adminserver.mapper.IsvKeysMapper;
|
||||||
import com.gitee.sop.adminserver.mapper.PermIsvRoleMapper;
|
import com.gitee.sop.adminserver.mapper.PermIsvRoleMapper;
|
||||||
import com.gitee.sop.adminserver.mapper.PermRoleMapper;
|
import com.gitee.sop.adminserver.mapper.PermRoleMapper;
|
||||||
import com.gitee.sop.adminserver.service.RoutePermissionService;
|
import com.gitee.sop.adminserver.service.RoutePermissionService;
|
||||||
@@ -39,6 +42,7 @@ import org.apache.commons.collections.CollectionUtils;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -57,6 +61,9 @@ public class IsvApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
IsvInfoMapper isvInfoMapper;
|
IsvInfoMapper isvInfoMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IsvKeysMapper isvKeysMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
PermIsvRoleMapper permIsvRoleMapper;
|
PermIsvRoleMapper permIsvRoleMapper;
|
||||||
|
|
||||||
@@ -71,20 +78,20 @@ public class IsvApi {
|
|||||||
@ApiDocField(name = "pageIndex", description = "第几页", dataType = DataType.INT, example = "1"),
|
@ApiDocField(name = "pageIndex", description = "第几页", dataType = DataType.INT, example = "1"),
|
||||||
@ApiDocField(name = "pageSize", description = "每页几条数据", dataType = DataType.INT, example = "10"),
|
@ApiDocField(name = "pageSize", description = "每页几条数据", dataType = DataType.INT, example = "10"),
|
||||||
@ApiDocField(name = "total", description = "每页几条数据", dataType = DataType.LONG, example = "100"),
|
@ApiDocField(name = "total", description = "每页几条数据", dataType = DataType.LONG, example = "100"),
|
||||||
@ApiDocField(name = "rows", description = "数据", dataType = DataType.ARRAY, elementClass = IsvVO.class)
|
@ApiDocField(name = "rows", description = "数据", dataType = DataType.ARRAY, elementClass = IsvInfoVO.class)
|
||||||
})
|
})
|
||||||
PageInfo<IsvVO> pageIsv(IsvPageParam param) {
|
PageInfo<IsvInfoVO> pageIsv(IsvPageParam param) {
|
||||||
Query query = Query.build(param);
|
Query query = Query.build(param);
|
||||||
PageInfo<IsvInfo> pageInfo = MapperUtil.query(isvInfoMapper, query);
|
PageInfo<IsvInfo> pageInfo = MapperUtil.query(isvInfoMapper, query);
|
||||||
List<IsvInfo> list = pageInfo.getList();
|
List<IsvInfo> list = pageInfo.getList();
|
||||||
|
|
||||||
List<IsvVO> retList = list.stream()
|
List<IsvInfoVO> retList = list.stream()
|
||||||
.map(isvInfo -> {
|
.map(isvInfo -> {
|
||||||
return buildIsvVO(isvInfo);
|
return buildIsvVO(isvInfo);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
PageInfo<IsvVO> pageInfoRet = new PageInfo<>();
|
PageInfo<IsvInfoVO> pageInfoRet = new PageInfo<>();
|
||||||
pageInfoRet.setTotal(pageInfo.getTotal());
|
pageInfoRet.setTotal(pageInfo.getTotal());
|
||||||
pageInfoRet.setList(retList);
|
pageInfoRet.setList(retList);
|
||||||
|
|
||||||
@@ -93,16 +100,30 @@ public class IsvApi {
|
|||||||
|
|
||||||
@Api(name = "isv.info.get")
|
@Api(name = "isv.info.get")
|
||||||
@ApiDocMethod(description = "获取isv")
|
@ApiDocMethod(description = "获取isv")
|
||||||
IsvVO getIsvVO(IdParam param) {
|
IsvInfoVO getIsvVO(IdParam param) {
|
||||||
IsvInfo isvInfo = isvInfoMapper.getById(param.getId());
|
IsvInfo isvInfo = isvInfoMapper.getById(param.getId());
|
||||||
return buildIsvVO(isvInfo);
|
return buildIsvVO(isvInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IsvVO buildIsvVO(IsvInfo isvInfo) {
|
@Api(name = "isv.keys.get")
|
||||||
|
@ApiDocMethod(description = "获取isv2")
|
||||||
|
IsvKeysVO getIsvKeys(@NotBlank(message = "appKey不能为空")
|
||||||
|
@ApiDocField(description = "appKey")
|
||||||
|
String appKey) {
|
||||||
|
IsvKeys isvKeys = isvKeysMapper.getByColumn("app_key", appKey);
|
||||||
|
IsvKeysVO isvDetailVO = new IsvKeysVO();
|
||||||
|
if (isvKeys != null) {
|
||||||
|
CopyUtil.copyProperties(isvKeys, isvDetailVO);
|
||||||
|
}
|
||||||
|
isvDetailVO.setAppKey(appKey);
|
||||||
|
return isvDetailVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IsvInfoVO buildIsvVO(IsvInfo isvInfo) {
|
||||||
if (isvInfo == null) {
|
if (isvInfo == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
IsvVO vo = new IsvVO();
|
IsvInfoVO vo = new IsvInfoVO();
|
||||||
CopyUtil.copyProperties(isvInfo, vo);
|
CopyUtil.copyProperties(isvInfo, vo);
|
||||||
vo.setRoleList(this.buildIsvRole(isvInfo));
|
vo.setRoleList(this.buildIsvRole(isvInfo));
|
||||||
return vo;
|
return vo;
|
||||||
@@ -134,44 +155,57 @@ public class IsvApi {
|
|||||||
@ApiDocMethod(description = "添加isv")
|
@ApiDocMethod(description = "添加isv")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void addIsv(IsvInfoFormAdd param) throws Exception {
|
public void addIsv(IsvInfoFormAdd param) throws Exception {
|
||||||
if (isvInfoMapper.getByColumn("app_key", param.getAppKey()) != null) {
|
String appKey = new SimpleDateFormat("yyyyMMdd").format(new Date()) + IdGen.nextId();
|
||||||
throw new BizException("appKey已存在");
|
|
||||||
}
|
|
||||||
formatForm(param);
|
|
||||||
IsvInfo rec = new IsvInfo();
|
IsvInfo rec = new IsvInfo();
|
||||||
|
rec.setAppKey(appKey);
|
||||||
CopyUtil.copyPropertiesIgnoreNull(param, rec);
|
CopyUtil.copyPropertiesIgnoreNull(param, rec);
|
||||||
isvInfoMapper.saveIgnoreNull(rec);
|
isvInfoMapper.saveIgnoreNull(rec);
|
||||||
if (CollectionUtils.isNotEmpty(param.getRoleCode())) {
|
if (CollectionUtils.isNotEmpty(param.getRoleCode())) {
|
||||||
this.saveIsvRole(rec, param.getRoleCode());
|
this.saveIsvRole(rec, param.getRoleCode());
|
||||||
}
|
}
|
||||||
|
IsvKeysGenVO isvKeysGenVO = this.createIsvKeys();
|
||||||
|
IsvKeys isvKeys = new IsvKeys();
|
||||||
|
CopyUtil.copyPropertiesIgnoreNull(isvKeysGenVO, isvKeys);
|
||||||
|
isvKeysMapper.saveIgnoreNull(isvKeys);
|
||||||
|
|
||||||
this.sendChannelMsg(rec);
|
this.sendChannelMsg(rec.getAppKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Api(name = "isv.info.update")
|
@Api(name = "isv.info.update")
|
||||||
@ApiDocMethod(description = "修改isv")
|
@ApiDocMethod(description = "修改isv")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateIsv(IsvInfoFormUpdate param) {
|
public void updateIsv(IsvInfoFormUpdate param) {
|
||||||
formatForm(param);
|
|
||||||
IsvInfo rec = isvInfoMapper.getById(param.getId());
|
IsvInfo rec = isvInfoMapper.getById(param.getId());
|
||||||
CopyUtil.copyPropertiesIgnoreNull(param, rec);
|
CopyUtil.copyPropertiesIgnoreNull(param, rec);
|
||||||
isvInfoMapper.updateIgnoreNull(rec);
|
isvInfoMapper.updateIgnoreNull(rec);
|
||||||
this.saveIsvRole(rec, param.getRoleCode());
|
this.saveIsvRole(rec, param.getRoleCode());
|
||||||
|
|
||||||
this.sendChannelMsg(rec);
|
this.sendChannelMsg(rec.getAppKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void formatForm(IsvInfoForm form) {
|
@Api(name = "isv.keys.update")
|
||||||
if (form.getSignType() == SIGN_TYPE_RSA2) {
|
@ApiDocMethod(description = "修改isv")
|
||||||
form.setSecret("");
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateIsvKeys(IsvKeysFormUpdate param) {
|
||||||
|
IsvKeys isvKeys = isvKeysMapper.getByColumn("app_key", param.getAppKey());
|
||||||
|
if (isvKeys == null) {
|
||||||
|
isvKeys = new IsvKeys();
|
||||||
|
CopyUtil.copyPropertiesIgnoreNull(param, isvKeys);
|
||||||
|
isvKeysMapper.saveIgnoreNull(isvKeys);
|
||||||
} else {
|
} else {
|
||||||
form.setPubKey("");
|
CopyUtil.copyPropertiesIgnoreNull(param, isvKeys);
|
||||||
form.setPriKey("");
|
isvKeysMapper.updateIgnoreNull(isvKeys);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendChannelMsg(IsvInfo rec) {
|
this.sendChannelMsg(isvKeys.getAppKey());
|
||||||
ChannelMsg channelMsg = new ChannelMsg("update", rec);
|
}
|
||||||
|
|
||||||
|
private void sendChannelMsg(String appKey) {
|
||||||
|
IsvDetailDTO isvDetail = isvInfoMapper.getIsvDetail(appKey);
|
||||||
|
if (isvDetail == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ChannelMsg channelMsg = new ChannelMsg("update", isvDetail);
|
||||||
String path = ZookeeperContext.getIsvInfoChannelPath();
|
String path = ZookeeperContext.getIsvInfoChannelPath();
|
||||||
String data = JSON.toJSONString(channelMsg);
|
String data = JSON.toJSONString(channelMsg);
|
||||||
try {
|
try {
|
||||||
@@ -183,23 +217,41 @@ public class IsvApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Api(name = "isv.form.gen")
|
private IsvKeysGenVO createIsvKeys() throws Exception {
|
||||||
@ApiDocMethod(description = "isv表单内容一键生成")
|
IsvKeysGenVO isvFormVO = new IsvKeysGenVO();
|
||||||
IsvFormVO createIsvForm() throws Exception {
|
|
||||||
IsvFormVO isvFormVO = new IsvFormVO();
|
|
||||||
String appKey = new SimpleDateFormat("yyyyMMdd").format(new Date()) + IdGen.nextId();
|
|
||||||
String secret = IdGen.uuid();
|
String secret = IdGen.uuid();
|
||||||
|
|
||||||
isvFormVO.setAppKey(appKey);
|
|
||||||
isvFormVO.setSecret(secret);
|
isvFormVO.setSecret(secret);
|
||||||
|
|
||||||
KeyStore keyStore = RSAUtil.createKeys();
|
RSATool rsaToolIsv = new RSATool(RSATool.KeyFormat.PKCS8, RSATool.KeyLength.LENGTH_2048);
|
||||||
isvFormVO.setPubKey(keyStore.getPublicKey());
|
RSATool.KeyStore keyStoreIsv = rsaToolIsv.createKeys();
|
||||||
isvFormVO.setPriKey(keyStore.getPrivateKey());
|
isvFormVO.setPublicKeyIsv(keyStoreIsv.getPublicKey());
|
||||||
|
isvFormVO.setPrivateKeyIsv(keyStoreIsv.getPrivateKey());
|
||||||
|
|
||||||
|
RSATool rsaToolPlatform = new RSATool(RSATool.KeyFormat.PKCS8, RSATool.KeyLength.LENGTH_2048);
|
||||||
|
RSATool.KeyStore keyStorePlatform = rsaToolPlatform.createKeys();
|
||||||
|
isvFormVO.setPublicKeyPlatform(keyStorePlatform.getPublicKey());
|
||||||
|
isvFormVO.setPrivateKeyPlatform(keyStorePlatform.getPrivateKey());
|
||||||
return isvFormVO;
|
return isvFormVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Api(name = "isv.keys.gen")
|
||||||
|
@ApiDocMethod(description = "生成公私钥")
|
||||||
|
RSATool.KeyStore createPubPriKey(IsvKeysGen param) throws Exception {
|
||||||
|
RSATool.KeyFormat format = RSATool.KeyFormat.PKCS8;
|
||||||
|
Byte keyFormat = param.getKeyFormat();
|
||||||
|
if (keyFormat != null && keyFormat == 2) {
|
||||||
|
format = RSATool.KeyFormat.PKCS1;
|
||||||
|
}
|
||||||
|
RSATool rsaTool = new RSATool(format, RSATool.KeyLength.LENGTH_2048);
|
||||||
|
return rsaTool.createKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Api(name = "isv.secret.gen")
|
||||||
|
@ApiDocMethod(description = "生成MD秘钥")
|
||||||
|
String createSecret() throws Exception {
|
||||||
|
return IdGen.uuid();
|
||||||
|
}
|
||||||
|
|
||||||
void saveIsvRole(IsvInfo isvInfo, List<String> roleCodeList) {
|
void saveIsvRole(IsvInfo isvInfo, List<String> roleCodeList) {
|
||||||
Query query = new Query();
|
Query query = new Query();
|
||||||
|
@@ -2,9 +2,7 @@ package com.gitee.sop.adminserver.api.isv.param;
|
|||||||
|
|
||||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -14,22 +12,6 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
public class IsvInfoForm {
|
public class IsvInfoForm {
|
||||||
|
|
||||||
@NotNull(message = "signType不能为null")
|
|
||||||
private Byte signType;
|
|
||||||
|
|
||||||
/** secret, 数据库字段:secret */
|
|
||||||
@ApiDocField(description = "secret")
|
|
||||||
@Length(max = 100,message = "secret长度不能超过100")
|
|
||||||
private String secret = "";
|
|
||||||
|
|
||||||
/** 公钥, 数据库字段:pub_key */
|
|
||||||
@ApiDocField(description = "pubKey")
|
|
||||||
private String pubKey;
|
|
||||||
|
|
||||||
/** 私钥, 数据库字段:pri_key */
|
|
||||||
@ApiDocField(description = "priKey")
|
|
||||||
private String priKey;
|
|
||||||
|
|
||||||
/** 0启用,1禁用, 数据库字段:status */
|
/** 0启用,1禁用, 数据库字段:status */
|
||||||
@ApiDocField(description = "状态:0:启用,1:禁用")
|
@ApiDocField(description = "状态:0:启用,1:禁用")
|
||||||
private Byte status = 0;
|
private Byte status = 0;
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
package com.gitee.sop.adminserver.api.isv.param;
|
package com.gitee.sop.adminserver.api.isv.param;
|
||||||
|
|
||||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.hibernate.validator.constraints.Length;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
@@ -13,9 +9,4 @@ import javax.validation.constraints.NotBlank;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class IsvInfoFormAdd extends IsvInfoForm {
|
public class IsvInfoFormAdd extends IsvInfoForm {
|
||||||
/** appKey, 数据库字段:app_key */
|
|
||||||
@ApiDocField(description = "appKey", required = true)
|
|
||||||
@NotBlank(message = "appKey不能为空")
|
|
||||||
@Length(max = 100,message = "appKey长度不能超过100")
|
|
||||||
private String appKey;
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,52 @@
|
|||||||
|
package com.gitee.sop.adminserver.api.isv.param;
|
||||||
|
|
||||||
|
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Max;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IsvKeysFormUpdate {
|
||||||
|
/** appKey, 数据库字段:app_key */
|
||||||
|
@ApiDocField(description = "appKey", example = "aaaa")
|
||||||
|
@NotBlank(message = "appKey不能为空")
|
||||||
|
@Length(max = 100,message = "appKey长度不能超过100")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/** secret, 数据库字段:secret */
|
||||||
|
@ApiDocField(description = "secret", example = "bbbb")
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
/** 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用), 数据库字段:key_format */
|
||||||
|
@ApiDocField(description = "秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)", example = "1")
|
||||||
|
@Min(value = 1, message = "秘钥格式错误")
|
||||||
|
@Max(value = 2, message = "秘钥格式错误")
|
||||||
|
private Byte keyFormat;
|
||||||
|
|
||||||
|
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||||
|
@ApiDocField(description = "开发者生成的公钥")
|
||||||
|
private String publicKeyIsv;
|
||||||
|
|
||||||
|
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */
|
||||||
|
@ApiDocField(description = "开发者生成的私钥")
|
||||||
|
private String privateKeyIsv;
|
||||||
|
|
||||||
|
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */
|
||||||
|
@ApiDocField(description = "平台生成的公钥")
|
||||||
|
private String publicKeyPlatform;
|
||||||
|
|
||||||
|
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||||
|
@ApiDocField(description = "平台生成的私钥")
|
||||||
|
private String privateKeyPlatform;
|
||||||
|
|
||||||
|
@ApiDocField(description = "签名类型:1:RSA2,2:MD5")
|
||||||
|
@NotNull(message = "signType不能为空")
|
||||||
|
private Byte signType;
|
||||||
|
}
|
@@ -0,0 +1,18 @@
|
|||||||
|
package com.gitee.sop.adminserver.api.isv.param;
|
||||||
|
|
||||||
|
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Max;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IsvKeysGen {
|
||||||
|
@ApiDocField(description = "秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)", example = "1")
|
||||||
|
@Min(value = 1, message = "秘钥格式错误")
|
||||||
|
@Max(value = 2, message = "秘钥格式错误")
|
||||||
|
private Byte keyFormat;
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
package com.gitee.sop.adminserver.api.isv.result;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IsvAppKeyGenVO {
|
||||||
|
private String appKey;
|
||||||
|
}
|
@@ -0,0 +1,34 @@
|
|||||||
|
package com.gitee.sop.adminserver.api.isv.result;
|
||||||
|
|
||||||
|
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IsvDetailDTO {
|
||||||
|
|
||||||
|
/** appKey, 数据库字段:app_key */
|
||||||
|
@ApiDocField(description = "appKey", example = "aaaa")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/** 0启用,1禁用, 数据库字段:status */
|
||||||
|
@ApiDocField(description = "状态:0启用,1禁用")
|
||||||
|
private Byte status;
|
||||||
|
|
||||||
|
// keys
|
||||||
|
|
||||||
|
/** secret, 数据库字段:secret */
|
||||||
|
@ApiDocField(description = "secret", example = "bbbb")
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||||
|
private String publicKeyIsv;
|
||||||
|
|
||||||
|
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||||
|
private String privateKeyPlatform;
|
||||||
|
|
||||||
|
@ApiDocField(description = "签名类型:1:RSA2,2:MD5")
|
||||||
|
private Byte signType;
|
||||||
|
}
|
@@ -1,23 +0,0 @@
|
|||||||
package com.gitee.sop.adminserver.api.isv.result;
|
|
||||||
|
|
||||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class IsvFormVO {
|
|
||||||
@ApiDocField(description = "appKey", example = "aaaa")
|
|
||||||
private String appKey;
|
|
||||||
|
|
||||||
@ApiDocField(description = "secret", example = "bbbb")
|
|
||||||
private String secret;
|
|
||||||
|
|
||||||
@ApiDocField(description = "pubKey")
|
|
||||||
private String pubKey;
|
|
||||||
|
|
||||||
@ApiDocField(description = "priKey")
|
|
||||||
private String priKey;
|
|
||||||
|
|
||||||
}
|
|
@@ -10,7 +10,7 @@ import java.util.List;
|
|||||||
* @author thc
|
* @author thc
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class IsvVO {
|
public class IsvInfoVO {
|
||||||
/** 数据库字段:id */
|
/** 数据库字段:id */
|
||||||
@ApiDocField(description = "id", example = "1")
|
@ApiDocField(description = "id", example = "1")
|
||||||
private Long id;
|
private Long id;
|
||||||
@@ -19,18 +19,6 @@ public class IsvVO {
|
|||||||
@ApiDocField(description = "appKey", example = "aaaa")
|
@ApiDocField(description = "appKey", example = "aaaa")
|
||||||
private String appKey;
|
private String appKey;
|
||||||
|
|
||||||
/** secret, 数据库字段:secret */
|
|
||||||
@ApiDocField(description = "secret", example = "bbbb")
|
|
||||||
private String secret;
|
|
||||||
|
|
||||||
/** 公钥, 数据库字段:pub_key */
|
|
||||||
@ApiDocField(description = "pubKey")
|
|
||||||
private String pubKey;
|
|
||||||
|
|
||||||
/** 私钥, 数据库字段:pri_key */
|
|
||||||
@ApiDocField(description = "priKey")
|
|
||||||
private String priKey;
|
|
||||||
|
|
||||||
/** 0启用,1禁用, 数据库字段:status */
|
/** 0启用,1禁用, 数据库字段:status */
|
||||||
@ApiDocField(description = "状态:0启用,1禁用")
|
@ApiDocField(description = "状态:0启用,1禁用")
|
||||||
private Byte status;
|
private Byte status;
|
@@ -0,0 +1,25 @@
|
|||||||
|
package com.gitee.sop.adminserver.api.isv.result;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IsvKeysGenVO {
|
||||||
|
/** secret, 数据库字段:secret */
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||||
|
private String publicKeyIsv;
|
||||||
|
|
||||||
|
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */
|
||||||
|
private String privateKeyIsv;
|
||||||
|
|
||||||
|
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */
|
||||||
|
private String publicKeyPlatform;
|
||||||
|
|
||||||
|
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||||
|
private String privateKeyPlatform;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
package com.gitee.sop.adminserver.api.isv.result;
|
||||||
|
|
||||||
|
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author thc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IsvKeysVO {
|
||||||
|
|
||||||
|
/** appKey, 数据库字段:app_key */
|
||||||
|
@ApiDocField(description = "appKey", example = "aaaa")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/** secret, 数据库字段:secret */
|
||||||
|
@ApiDocField(description = "secret", example = "bbbb")
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
/** 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用), 数据库字段:key_format */
|
||||||
|
private Byte keyFormat = 1;
|
||||||
|
|
||||||
|
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||||
|
private String publicKeyIsv;
|
||||||
|
|
||||||
|
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */
|
||||||
|
private String privateKeyIsv;
|
||||||
|
|
||||||
|
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */
|
||||||
|
private String publicKeyPlatform;
|
||||||
|
|
||||||
|
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||||
|
private String privateKeyPlatform;
|
||||||
|
|
||||||
|
@ApiDocField(description = "签名类型:1:RSA2,2:MD5")
|
||||||
|
private Byte signType = 1;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,410 @@
|
|||||||
|
package com.gitee.sop.adminserver.common;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.bouncycastle.asn1.ASN1Encodable;
|
||||||
|
import org.bouncycastle.asn1.ASN1Primitive;
|
||||||
|
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA加解密工具<br>
|
||||||
|
*
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
public class RSATool {
|
||||||
|
public static String RSA_ALGORITHM = "RSA";
|
||||||
|
|
||||||
|
private KeyFormat keyFormat;
|
||||||
|
private KeyLength keyLength;
|
||||||
|
|
||||||
|
public RSATool(KeyFormat keyFormat, KeyLength keyLength) {
|
||||||
|
this.keyFormat = keyFormat;
|
||||||
|
this.keyLength = keyLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建公钥私钥
|
||||||
|
*
|
||||||
|
* @return 返回公私钥对
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public KeyStore createKeys() throws Exception {
|
||||||
|
KeyPairGenerator keyPairGeno = KeyPairGenerator.getInstance(RSA_ALGORITHM);
|
||||||
|
keyPairGeno.initialize(keyLength.getLength());
|
||||||
|
KeyPair keyPair = keyPairGeno.generateKeyPair();
|
||||||
|
|
||||||
|
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||||
|
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||||
|
|
||||||
|
KeyStore keyStore = new KeyStore();
|
||||||
|
if (this.keyFormat == KeyFormat.PKCS1) {
|
||||||
|
keyStore.setPublicKey(Base64.encodeBase64String(publicKey.getEncoded()));
|
||||||
|
keyStore.setPrivateKey(convertPkcs8ToPkcs1(privateKey.getEncoded()));
|
||||||
|
} else {
|
||||||
|
keyStore.setPublicKey(Base64.encodeBase64String(publicKey.getEncoded()));
|
||||||
|
keyStore.setPrivateKey(Base64.encodeBase64String(privateKey.getEncoded()));
|
||||||
|
}
|
||||||
|
return keyStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公钥对象
|
||||||
|
*
|
||||||
|
* @param pubKeyData 公钥
|
||||||
|
* @return 返回公钥对象
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public RSAPublicKey getPublicKey(byte[] pubKeyData) throws Exception {
|
||||||
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKeyData);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
||||||
|
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公钥对象
|
||||||
|
*
|
||||||
|
* @param pubKey 公钥
|
||||||
|
* @return 返回私钥对象
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public RSAPublicKey getPublicKey(String pubKey) throws Exception {
|
||||||
|
return getPublicKey(Base64.decodeBase64(pubKey));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取私钥对象
|
||||||
|
*
|
||||||
|
* @param priKey 私钥
|
||||||
|
* @return 私钥对象
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public RSAPrivateKey getPrivateKey(String priKey) throws Exception {
|
||||||
|
return getPrivateKey(Base64.decodeBase64(priKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过私钥byte[]将公钥还原,适用于RSA算法
|
||||||
|
*
|
||||||
|
* @param keyBytes
|
||||||
|
* @return 返回私钥
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public RSAPrivateKey getPrivateKey(byte[] keyBytes) throws Exception {
|
||||||
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
||||||
|
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公钥加密
|
||||||
|
*
|
||||||
|
* @param data 待加密内容
|
||||||
|
* @param publicKey 公钥
|
||||||
|
* @return 返回密文
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String encryptByPublicKey(String data, RSAPublicKey publicKey) throws Exception {
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
// 模长
|
||||||
|
int key_len = publicKey.getModulus().bitLength() / 8;
|
||||||
|
// 加密数据长度 <= 模长-11
|
||||||
|
String[] datas = splitString(data, key_len - 11);
|
||||||
|
String mi = "";
|
||||||
|
// 如果明文长度大于模长-11则要分组加密
|
||||||
|
for (String s : datas) {
|
||||||
|
mi += bcd2Str(cipher.doFinal(s.getBytes()));
|
||||||
|
}
|
||||||
|
return mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String encryptByPrivateKey(String data, String privateKey) throws Exception {
|
||||||
|
return encryptByPrivateKey(data, getPrivateKey(privateKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私钥加密
|
||||||
|
*
|
||||||
|
* @param data 待加密数据
|
||||||
|
* @param privateKey 私钥
|
||||||
|
* @return 返回密文
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String encryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception {
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||||
|
// 模长
|
||||||
|
int key_len = privateKey.getModulus().bitLength() / 8;
|
||||||
|
// 加密数据长度 <= 模长-11
|
||||||
|
String[] datas = splitString(data, key_len - 11);
|
||||||
|
String mi = "";
|
||||||
|
// 如果明文长度大于模长-11则要分组加密
|
||||||
|
for (String s : datas) {
|
||||||
|
mi += bcd2Str(cipher.doFinal(s.getBytes()));
|
||||||
|
}
|
||||||
|
return mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String decryptByPrivateKey(String data, String privateKey) throws Exception {
|
||||||
|
return decryptByPrivateKey(data, getPrivateKey(privateKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私钥解密
|
||||||
|
*
|
||||||
|
* @param data 待解密内容
|
||||||
|
* @param privateKey 私钥
|
||||||
|
* @return 返回明文
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception {
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
|
// 模长
|
||||||
|
int key_len = privateKey.getModulus().bitLength() / 8;
|
||||||
|
byte[] bytes = data.getBytes();
|
||||||
|
byte[] bcd = ASCII_To_BCD(bytes, bytes.length);
|
||||||
|
// 如果密文长度大于模长则要分组解密
|
||||||
|
String ming = "";
|
||||||
|
byte[][] arrays = splitArray(bcd, key_len);
|
||||||
|
for (byte[] arr : arrays) {
|
||||||
|
ming += new String(cipher.doFinal(arr));
|
||||||
|
}
|
||||||
|
return ming;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公钥解密
|
||||||
|
*
|
||||||
|
* @param data 待解密内容
|
||||||
|
* @param rsaPublicKey 公钥
|
||||||
|
* @return 返回明文
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String decryptByPublicKey(String data, RSAPublicKey rsaPublicKey) throws Exception {
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, rsaPublicKey);
|
||||||
|
// 模长
|
||||||
|
int key_len = rsaPublicKey.getModulus().bitLength() / 8;
|
||||||
|
byte[] bytes = data.getBytes();
|
||||||
|
byte[] bcd = ASCII_To_BCD(bytes, bytes.length);
|
||||||
|
// 如果密文长度大于模长则要分组解密
|
||||||
|
String ming = "";
|
||||||
|
byte[][] arrays = splitArray(bcd, key_len);
|
||||||
|
for (byte[] arr : arrays) {
|
||||||
|
ming += new String(cipher.doFinal(arr));
|
||||||
|
}
|
||||||
|
return ming;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String convertPkcs8ToPkcs1(byte[] privateKeyData) throws Exception{
|
||||||
|
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privateKeyData);
|
||||||
|
ASN1Encodable encodable = pkInfo.parsePrivateKey();
|
||||||
|
ASN1Primitive primitive = encodable.toASN1Primitive();
|
||||||
|
byte[] privateKeyPKCS1 = primitive.getEncoded();
|
||||||
|
return Base64.encodeBase64String(privateKeyPKCS1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ASCII码转BCD码
|
||||||
|
*/
|
||||||
|
public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {
|
||||||
|
byte[] bcd = new byte[asc_len / 2];
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < (asc_len + 1) / 2; i++) {
|
||||||
|
bcd[i] = asc_to_bcd(ascii[j++]);
|
||||||
|
bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++]) & 0xff) + (bcd[i] << 4));
|
||||||
|
}
|
||||||
|
return bcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte asc_to_bcd(byte asc) {
|
||||||
|
byte bcd;
|
||||||
|
|
||||||
|
if ((asc >= '0') && (asc <= '9')) {
|
||||||
|
bcd = (byte) (asc - '0');
|
||||||
|
} else if ((asc >= 'A') && (asc <= 'F')) {
|
||||||
|
bcd = (byte) (asc - 'A' + 10);
|
||||||
|
} else if ((asc >= 'a') && (asc <= 'f')) {
|
||||||
|
bcd = (byte) (asc - 'a' + 10);
|
||||||
|
} else {
|
||||||
|
bcd = (byte) (asc - 48);
|
||||||
|
}
|
||||||
|
return bcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BCD转字符串
|
||||||
|
*/
|
||||||
|
public String bcd2Str(byte[] bytes) {
|
||||||
|
char[] temp = new char[bytes.length * 2];
|
||||||
|
char val;
|
||||||
|
|
||||||
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
|
||||||
|
temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
|
||||||
|
|
||||||
|
val = (char) (bytes[i] & 0x0f);
|
||||||
|
temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
|
||||||
|
}
|
||||||
|
return new String(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拆分字符串
|
||||||
|
*/
|
||||||
|
public String[] splitString(String string, int len) {
|
||||||
|
int x = string.length() / len;
|
||||||
|
int y = string.length() % len;
|
||||||
|
int z = 0;
|
||||||
|
if (y != 0) {
|
||||||
|
z = 1;
|
||||||
|
}
|
||||||
|
String[] strings = new String[x + z];
|
||||||
|
String str = "";
|
||||||
|
for (int i = 0; i < x + z; i++) {
|
||||||
|
if (i == x + z - 1 && y != 0) {
|
||||||
|
str = string.substring(i * len, i * len + y);
|
||||||
|
} else {
|
||||||
|
str = string.substring(i * len, i * len + len);
|
||||||
|
}
|
||||||
|
strings[i] = str;
|
||||||
|
}
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拆分数组
|
||||||
|
*/
|
||||||
|
public byte[][] splitArray(byte[] data, int len) {
|
||||||
|
int x = data.length / len;
|
||||||
|
int y = data.length % len;
|
||||||
|
int z = 0;
|
||||||
|
if (y != 0) {
|
||||||
|
z = 1;
|
||||||
|
}
|
||||||
|
byte[][] arrays = new byte[x + z][];
|
||||||
|
byte[] arr;
|
||||||
|
for (int i = 0; i < x + z; i++) {
|
||||||
|
arr = new byte[len];
|
||||||
|
if (i == x + z - 1 && y != 0) {
|
||||||
|
System.arraycopy(data, i * len, arr, 0, y);
|
||||||
|
} else {
|
||||||
|
System.arraycopy(data, i * len, arr, 0, len);
|
||||||
|
}
|
||||||
|
arrays[i] = arr;
|
||||||
|
}
|
||||||
|
return arrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum KeyLength {
|
||||||
|
LENGTH_1024(1024), LENGTH_2048(2048);
|
||||||
|
private int length;
|
||||||
|
|
||||||
|
KeyLength(int length) {
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class KeyStore {
|
||||||
|
private String publicKey;
|
||||||
|
private String privateKey;
|
||||||
|
|
||||||
|
public String getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicKey(String publicKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(String privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum KeyFormat {
|
||||||
|
PKCS1("RSA/ECB/PKCS1Padding"), PKCS8("RSA");
|
||||||
|
private String cipherAlgorithm;
|
||||||
|
|
||||||
|
KeyFormat(String cipherAlgorithm) {
|
||||||
|
this.cipherAlgorithm = cipherAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCipherAlgorithm() {
|
||||||
|
return cipherAlgorithm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyFormat getKeyFormat() {
|
||||||
|
return keyFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyLength getKeyLength() {
|
||||||
|
return keyLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------ Test ------------
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
RSATool rsa_pkcs8_1024 = new RSATool(KeyFormat.PKCS8, KeyLength.LENGTH_1024);
|
||||||
|
RSATool rsa_pkcs8_2048 = new RSATool(KeyFormat.PKCS8, KeyLength.LENGTH_2048);
|
||||||
|
|
||||||
|
doTest(rsa_pkcs8_1024);
|
||||||
|
doTest(rsa_pkcs8_2048);
|
||||||
|
|
||||||
|
// PKCS在Java环境无法测试,可以生成一对,到非java平台测试,如C#
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void doTest(RSATool rsaTool) throws Exception {
|
||||||
|
System.out.println("秘钥格式:" + rsaTool.keyFormat.name() + ", 秘钥长度:" + rsaTool.keyLength.getLength());
|
||||||
|
KeyStore keys = rsaTool.createKeys();
|
||||||
|
String pubKey = keys.getPublicKey();
|
||||||
|
System.out.println("pubKey:");
|
||||||
|
System.out.println(pubKey);
|
||||||
|
String priKey = keys.getPrivateKey();
|
||||||
|
System.out.println("priKey:");
|
||||||
|
System.out.println(priKey);
|
||||||
|
System.out.println("--------");
|
||||||
|
|
||||||
|
String ming = "你好,abc123~!@=";
|
||||||
|
// 用公钥加密
|
||||||
|
String mi = rsaTool.encryptByPublicKey(ming, rsaTool.getPublicKey(pubKey));
|
||||||
|
System.out.println("mi : " + mi);
|
||||||
|
// 用私钥解密
|
||||||
|
String ming2 = rsaTool.decryptByPrivateKey(mi, rsaTool.getPrivateKey(priKey));
|
||||||
|
System.out.println("ming : " + ming2 + ", 结果:" + ming2.equals(ming));
|
||||||
|
|
||||||
|
// 用私钥加密
|
||||||
|
String mi2 = rsaTool.encryptByPrivateKey(ming, rsaTool.getPrivateKey(priKey));
|
||||||
|
|
||||||
|
System.out.println("mi2 : " + mi2);
|
||||||
|
// 用公钥解密
|
||||||
|
String ming3 = rsaTool.decryptByPublicKey(mi2, rsaTool.getPublicKey(pubKey));
|
||||||
|
System.out.println("ming3 : " + ming3 + ", 结果:" + ming3.equals(ming));
|
||||||
|
System.out.println("---------------------");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
@@ -2,13 +2,13 @@ package com.gitee.sop.adminserver.entity;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +19,7 @@ import javax.persistence.Table;
|
|||||||
*/
|
*/
|
||||||
@Table(name = "admin_user_info")
|
@Table(name = "admin_user_info")
|
||||||
@Data
|
@Data
|
||||||
public class AdminUserInfo {
|
public class AdminUserInfo implements Serializable {
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@@ -28,21 +28,9 @@ public class IsvInfo {
|
|||||||
/** appKey, 数据库字段:app_key */
|
/** appKey, 数据库字段:app_key */
|
||||||
private String appKey;
|
private String appKey;
|
||||||
|
|
||||||
/** secret, 数据库字段:secret */
|
|
||||||
private String secret;
|
|
||||||
|
|
||||||
/** 公钥, 数据库字段:pub_key */
|
|
||||||
private String pubKey;
|
|
||||||
|
|
||||||
/** 私钥, 数据库字段:pri_key */
|
|
||||||
private String priKey;
|
|
||||||
|
|
||||||
/** 1启用,2禁用, 数据库字段:status */
|
/** 1启用,2禁用, 数据库字段:status */
|
||||||
private Byte status;
|
private Byte status;
|
||||||
|
|
||||||
/** 1:RSA2,2:MD5, 数据库字段:sign_type */
|
|
||||||
private Byte signType;
|
|
||||||
|
|
||||||
/** 数据库字段:gmt_create */
|
/** 数据库字段:gmt_create */
|
||||||
private Date gmtCreate;
|
private Date gmtCreate;
|
||||||
|
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
package com.gitee.sop.adminserver.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表名:isv_keys
|
||||||
|
* 备注:ISV秘钥
|
||||||
|
*
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Table(name = "isv_keys")
|
||||||
|
@Data
|
||||||
|
public class IsvKeys {
|
||||||
|
@Id
|
||||||
|
@Column(name = "id")
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
/** 数据库字段:id */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 数据库字段:app_key */
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/** 1:RSA2,2:MD5, 数据库字段:sign_type */
|
||||||
|
private Byte signType;
|
||||||
|
|
||||||
|
/** isv_info.sign_type=2时使用, 数据库字段:secret */
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
/** 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用), 数据库字段:key_format */
|
||||||
|
private Byte keyFormat;
|
||||||
|
|
||||||
|
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||||
|
private String publicKeyIsv;
|
||||||
|
|
||||||
|
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */
|
||||||
|
private String privateKeyIsv;
|
||||||
|
|
||||||
|
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */
|
||||||
|
private String publicKeyPlatform;
|
||||||
|
|
||||||
|
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||||
|
private String privateKeyPlatform;
|
||||||
|
|
||||||
|
/** 数据库字段:gmt_create */
|
||||||
|
private Date gmtCreate;
|
||||||
|
|
||||||
|
/** 数据库字段:gmt_modified */
|
||||||
|
private Date gmtModified;
|
||||||
|
}
|
@@ -2,11 +2,29 @@ package com.gitee.sop.adminserver.mapper;
|
|||||||
|
|
||||||
import com.gitee.fastmybatis.core.mapper.CrudMapper;
|
import com.gitee.fastmybatis.core.mapper.CrudMapper;
|
||||||
|
|
||||||
|
import com.gitee.sop.adminserver.api.isv.result.IsvDetailDTO;
|
||||||
import com.gitee.sop.adminserver.entity.IsvInfo;
|
import com.gitee.sop.adminserver.entity.IsvInfo;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
*/
|
*/
|
||||||
public interface IsvInfoMapper extends CrudMapper<IsvInfo, Long> {
|
public interface IsvInfoMapper extends CrudMapper<IsvInfo, Long> {
|
||||||
|
|
||||||
|
@Select("SELECT " +
|
||||||
|
" t.app_key appKey " +
|
||||||
|
" ,t.status " +
|
||||||
|
" ,t2.sign_type signType " +
|
||||||
|
" ,t2.secret " +
|
||||||
|
" ,t2.public_key_isv publicKeyIsv " +
|
||||||
|
" ,t2.private_key_isv privateKeyIsv " +
|
||||||
|
" ,t2.public_key_platform publicKeyPlatform " +
|
||||||
|
" ,t2.private_key_platform privateKeyPlatform " +
|
||||||
|
"FROM isv_info t " +
|
||||||
|
"INNER JOIN isv_keys t2 ON t.app_key = t2.app_key " +
|
||||||
|
"WHERE t.app_key = #{appKey}")
|
||||||
|
IsvDetailDTO getIsvDetail(@Param("appKey") String appKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,12 @@
|
|||||||
|
package com.gitee.sop.adminserver.mapper;
|
||||||
|
|
||||||
|
import com.gitee.fastmybatis.core.mapper.CrudMapper;
|
||||||
|
|
||||||
|
import com.gitee.sop.adminserver.entity.IsvKeys;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
public interface IsvKeysMapper extends CrudMapper<IsvKeys, Long> {
|
||||||
|
}
|
@@ -1 +1 @@
|
|||||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,o,c=t[0],i=t[1],f=t[2],l=0,s=[];l<c.length;l++)o=c[l],u[o]&&s.push(u[o][0]),u[o]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);d&&d(t);while(s.length)s.shift()();return a.push.apply(a,f||[]),n()}function n(){for(var e,t=0;t<a.length;t++){for(var n=a[t],r=!0,o=1;o<n.length;o++){var c=n[o];0!==u[c]&&(r=!1)}r&&(a.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},o={runtime:0},u={runtime:0},a=[];function c(e){return i.p+"static/js/"+({}[e]||e)+"."+{"chunk-238a81e9":"5955f13d","chunk-2d221836":"574c9ab6","chunk-2d22c2e3":"46f37153","chunk-37401378":"4e39ec9b","chunk-4a59cbe4":"b5e74cc4","chunk-50417551":"ea8ad933","chunk-6a68a33e":"f59ae895","chunk-ea2e58a4":"f3f85b0e"}[e]+".js"}function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.e=function(e){var t=[],n={"chunk-238a81e9":1,"chunk-37401378":1,"chunk-50417551":1,"chunk-6a68a33e":1,"chunk-ea2e58a4":1};o[e]?t.push(o[e]):0!==o[e]&&n[e]&&t.push(o[e]=new Promise(function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-238a81e9":"e8e2beee","chunk-2d221836":"31d6cfe0","chunk-2d22c2e3":"31d6cfe0","chunk-37401378":"a43114f3","chunk-4a59cbe4":"31d6cfe0","chunk-50417551":"8bd9f4f4","chunk-6a68a33e":"3b12267b","chunk-ea2e58a4":"d10599db"}[e]+".css",u=i.p+r,a=document.getElementsByTagName("link"),c=0;c<a.length;c++){var f=a[c],l=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(l===r||l===u))return t()}var s=document.getElementsByTagName("style");for(c=0;c<s.length;c++){f=s[c],l=f.getAttribute("data-href");if(l===r||l===u)return t()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=t,d.onerror=function(t){var r=t&&t.target&&t.target.src||u,a=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");a.code="CSS_CHUNK_LOAD_FAILED",a.request=r,delete o[e],d.parentNode.removeChild(d),n(a)},d.href=u;var h=document.getElementsByTagName("head")[0];h.appendChild(d)}).then(function(){o[e]=0}));var r=u[e];if(0!==r)if(r)t.push(r[2]);else{var a=new Promise(function(t,n){r=u[e]=[t,n]});t.push(r[2]=a);var f,l=document.createElement("script");l.charset="utf-8",l.timeout=120,i.nc&&l.setAttribute("nonce",i.nc),l.src=c(e),f=function(t){l.onerror=l.onload=null,clearTimeout(s);var n=u[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src,a=new Error("Loading chunk "+e+" failed.\n("+r+": "+o+")");a.type=r,a.request=o,n[1](a)}u[e]=void 0}};var s=setTimeout(function(){f({type:"timeout",target:l})},12e4);l.onerror=l.onload=f,document.head.appendChild(l)}return Promise.all(t)},i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],l=f.push.bind(f);f.push=t,f=f.slice();for(var s=0;s<f.length;s++)t(f[s]);var d=l;n()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.3e92351d.js></script></body></html>
|
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,c,a=t[0],i=t[1],f=t[2],l=0,h=[];l<a.length;l++)c=a[l],u[c]&&h.push(u[c][0]),u[c]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);s&&s(t);while(h.length)h.shift()();return o.push.apply(o,f||[]),n()}function n(){for(var e,t=0;t<o.length;t++){for(var n=o[t],r=!0,c=1;c<n.length;c++){var a=n[c];0!==u[a]&&(r=!1)}r&&(o.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(e){return i.p+"static/js/"+({}[e]||e)+"."+{"chunk-238a81e9":"5955f13d","chunk-25908fca":"29365d11","chunk-29e7142c":"994a3ac0","chunk-2d22c2e3":"46f37153","chunk-37401378":"4e39ec9b","chunk-4a59cbe4":"b5e74cc4","chunk-5f00e420":"5e409513","chunk-6a68a33e":"f59ae895","chunk-73b2dcec":"37433095"}[e]+".js"}function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.e=function(e){var t=[],n={"chunk-238a81e9":1,"chunk-25908fca":1,"chunk-29e7142c":1,"chunk-37401378":1,"chunk-5f00e420":1,"chunk-6a68a33e":1,"chunk-73b2dcec":1};c[e]?t.push(c[e]):0!==c[e]&&n[e]&&t.push(c[e]=new Promise(function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-238a81e9":"e8e2beee","chunk-25908fca":"89ab33e8","chunk-29e7142c":"d10599db","chunk-2d22c2e3":"31d6cfe0","chunk-37401378":"a43114f3","chunk-4a59cbe4":"31d6cfe0","chunk-5f00e420":"aeebecd4","chunk-6a68a33e":"3b12267b","chunk-73b2dcec":"99cf6327"}[e]+".css",u=i.p+r,o=document.getElementsByTagName("link"),a=0;a<o.length;a++){var f=o[a],l=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(l===r||l===u))return t()}var h=document.getElementsByTagName("style");for(a=0;a<h.length;a++){f=h[a],l=f.getAttribute("data-href");if(l===r||l===u)return t()}var s=document.createElement("link");s.rel="stylesheet",s.type="text/css",s.onload=t,s.onerror=function(t){var r=t&&t.target&&t.target.src||u,o=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");o.code="CSS_CHUNK_LOAD_FAILED",o.request=r,delete c[e],s.parentNode.removeChild(s),n(o)},s.href=u;var d=document.getElementsByTagName("head")[0];d.appendChild(s)}).then(function(){c[e]=0}));var r=u[e];if(0!==r)if(r)t.push(r[2]);else{var o=new Promise(function(t,n){r=u[e]=[t,n]});t.push(r[2]=o);var f,l=document.createElement("script");l.charset="utf-8",l.timeout=120,i.nc&&l.setAttribute("nonce",i.nc),l.src=a(e),f=function(t){l.onerror=l.onload=null,clearTimeout(h);var n=u[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),c=t&&t.target&&t.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,n[1](o)}u[e]=void 0}};var h=setTimeout(function(){f({type:"timeout",target:l})},12e4);l.onerror=l.onload=f,document.head.appendChild(l)}return Promise.all(t)},i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],l=f.push.bind(f);f.push=t,f=f.slice();for(var h=0;h<f.length;h++)t(f[h]);var s=l;n()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.3cc1fa6b.js></script></body></html>
|
@@ -0,0 +1 @@
|
|||||||
|
.gen-key{margin-bottom:0!important}fieldset{border:1px solid #ccc;color:grey;margin-left:40px;margin-bottom:20px}fieldset label{width:110px!important}fieldset .el-form-item__content{margin-left:110px!important}.key-view .el-form-item{margin-bottom:10px!important}
|
@@ -1 +0,0 @@
|
|||||||
.limit-tip[data-v-9b075514]{cursor:pointer;margin-left:10px}
|
|
@@ -0,0 +1 @@
|
|||||||
|
.custom-tree-node{-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-size:14px;padding-right:8px}.el-input.is-disabled .el-input__inner,.el-radio__input.is-disabled+span.el-radio__label{color:#909399}.limit-tip[data-v-0ec28e9a]{cursor:pointer;margin-left:10px}
|
@@ -0,0 +1 @@
|
|||||||
|
.gen-key{margin-bottom:0!important}fieldset{border:1px solid #ccc;color:grey;margin-left:40px;margin-bottom:20px}fieldset label{width:110px!important}fieldset .el-form-item__content{margin-left:110px!important}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,21 @@
|
|||||||
|
package com.gitee.sop.adminserver;
|
||||||
|
|
||||||
|
import com.gitee.sop.adminserver.api.isv.result.IsvDetailDTO;
|
||||||
|
import com.gitee.sop.adminserver.mapper.IsvInfoMapper;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
public class IsvInfoMapperTest extends SopAdminServerApplicationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IsvInfoMapper isvInfoMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGet() {
|
||||||
|
IsvDetailDTO isvDetail = isvInfoMapper.getIsvDetail("2019032617262200001");
|
||||||
|
System.out.println(isvDetail);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package com.gitee.durcframework.easyopen.server;
|
package com.gitee.sop.adminserver;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@@ -1,4 +1,4 @@
|
|||||||
package com.gitee.durcframework.easyopen.server;
|
package com.gitee.sop.adminserver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
@@ -1,4 +1,4 @@
|
|||||||
package com.gitee.durcframework.easyopen.server;
|
package com.gitee.sop.adminserver;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
@@ -92,12 +92,20 @@ export const constantRoutes = [
|
|||||||
path: '/isv',
|
path: '/isv',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
meta: { title: 'ISV管理', icon: 'user' },
|
meta: { title: 'ISV管理', icon: 'user' },
|
||||||
|
redirect: '/isv/list',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'list',
|
path: 'list',
|
||||||
name: 'IsvList',
|
name: 'IsvList',
|
||||||
component: () => import('@/views/isv/index'),
|
component: () => import('@/views/isv/index'),
|
||||||
meta: { title: 'ISV列表' }
|
meta: { title: 'ISV列表' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'keys',
|
||||||
|
name: 'Keys',
|
||||||
|
component: () => import('@/views/isv/keys'),
|
||||||
|
hidden: true,
|
||||||
|
meta: { title: '秘钥管理' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@@ -8,7 +8,7 @@ import { getToken, removeToken } from './auth'
|
|||||||
// 创建axios实例
|
// 创建axios实例
|
||||||
const client = axios.create({
|
const client = axios.create({
|
||||||
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
|
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
|
||||||
timeout: 10000 // 请求超时时间
|
timeout: 60000 // 请求超时时间,60秒
|
||||||
})
|
})
|
||||||
|
|
||||||
Object.assign(Vue.prototype, {
|
Object.assign(Vue.prototype, {
|
||||||
|
@@ -25,32 +25,13 @@
|
|||||||
label="appKey"
|
label="appKey"
|
||||||
width="250"
|
width="250"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
|
||||||
prop="secret"
|
|
||||||
label="secret"
|
|
||||||
width="80"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button v-if="scope.row.signType === 2" type="text" size="mini" @click="onShowSecret(scope.row)">查看</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop=""
|
prop=""
|
||||||
label="公私钥"
|
label="秘钥"
|
||||||
width="80"
|
width="80"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button v-if="scope.row.signType === 1" type="text" size="mini" @click="onShowPriPubKey(scope.row)">查看</el-button>
|
<el-button type="text" size="mini" @click="onShowKeys(scope.row)">查看</el-button>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="signType"
|
|
||||||
label="签名类型"
|
|
||||||
width="80"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span v-if="scope.row.signType === 1">RSA2</span>
|
|
||||||
<span v-if="scope.row.signType === 2">MD5</span>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@@ -83,11 +64,11 @@
|
|||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="操作"
|
label="操作"
|
||||||
fixed="right"
|
width="150"
|
||||||
width="100"
|
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" size="mini" @click="onTableUpdate(scope.row)">修改</el-button>
|
<el-button type="text" size="mini" @click="onTableUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button type="text" size="mini" @click="onKeysUpdate(scope.row)">秘钥管理</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -116,26 +97,9 @@
|
|||||||
label-width="120px"
|
label-width="120px"
|
||||||
size="mini"
|
size="mini"
|
||||||
>
|
>
|
||||||
<el-form-item label="">
|
<el-form-item label="appKey">
|
||||||
<el-button size="mini" @click="onDataGen">一键生成数据</el-button>
|
<span v-if="isvDialogFormData.id === 0" style="color: gray;">(系统自动生成)</span>
|
||||||
</el-form-item>
|
<span v-else>{{ isvDialogFormData.appKey }}</span>
|
||||||
<el-form-item prop="appKey" label="appKey">
|
|
||||||
<el-input v-model="isvDialogFormData.appKey" size="mini" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item prop="signType" label="签名方式">
|
|
||||||
<el-radio-group v-model="isvDialogFormData.signType">
|
|
||||||
<el-radio :label="1" name="status">RSA2</el-radio>
|
|
||||||
<el-radio :label="2" name="status">MD5</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-show="isvDialogFormData.signType === 2" prop="secret" label="secret">
|
|
||||||
<el-input v-model="isvDialogFormData.secret" size="mini" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-show="isvDialogFormData.signType === 1" prop="pubKey" label="公钥">
|
|
||||||
<el-input v-model="isvDialogFormData.pubKey" type="textarea" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-show="isvDialogFormData.signType === 1" prop="priKey" label="私钥">
|
|
||||||
<el-input v-model="isvDialogFormData.priKey" type="textarea" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="角色">
|
<el-form-item label="角色">
|
||||||
<el-checkbox-group v-model="isvDialogFormData.roleCode">
|
<el-checkbox-group v-model="isvDialogFormData.roleCode">
|
||||||
@@ -154,31 +118,75 @@
|
|||||||
<el-button type="primary" @click="onIsvDialogSave">保 存</el-button>
|
<el-button type="primary" @click="onIsvDialogSave">保 存</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<!--view keys dialog-->
|
||||||
|
<el-dialog
|
||||||
|
title="秘钥信息"
|
||||||
|
:visible.sync="isvKeysDialogVisible"
|
||||||
|
@close="resetForm('isvKeysFrom')"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="isvKeysFrom"
|
||||||
|
:model="isvKeysFormData"
|
||||||
|
label-width="160px"
|
||||||
|
size="mini"
|
||||||
|
class="key-view"
|
||||||
|
>
|
||||||
|
<el-form-item label="">
|
||||||
|
<el-alert
|
||||||
|
title="带 ★ 的分配给开发者"
|
||||||
|
type="warning"
|
||||||
|
:closable="false"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="selfLabel('appKey')">
|
||||||
|
<span>{{ isvKeysFormData.appKey }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="签名方式">
|
||||||
|
<span v-if="isvKeysFormData.signType === 1">RSA2</span>
|
||||||
|
<span v-if="isvKeysFormData.signType === 2">MD5</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-show="showKeys()" label="秘钥格式">
|
||||||
|
<span v-if="isvKeysFormData.keyFormat === 1">PKCS8(JAVA适用)</span>
|
||||||
|
<span v-if="isvKeysFormData.keyFormat === 2">PKCS1(非JAVA适用)</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-show="isvKeysFormData.signType === 2" :label="selfLabel('secret')">
|
||||||
|
<span>{{ isvKeysFormData.secret }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<fieldset v-show="showKeys()">
|
||||||
|
<legend>ISV公私钥</legend>
|
||||||
|
<el-form-item label="ISV公钥">
|
||||||
|
<el-input v-model="isvKeysFormData.publicKeyIsv" type="textarea" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="selfLabel('ISV私钥')">
|
||||||
|
<el-input v-model="isvKeysFormData.privateKeyIsv" type="textarea" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset v-show="showKeys()">
|
||||||
|
<legend>平台公私钥</legend>
|
||||||
|
<el-form-item :label="selfLabel('平台公钥')">
|
||||||
|
<el-input v-model="isvKeysFormData.publicKeyPlatform" type="textarea" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="privateKeyPlatform" label="平台私钥">
|
||||||
|
<el-input v-model="isvKeysFormData.privateKeyPlatform" type="textarea" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
</fieldset>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="isvKeysDialogVisible = false">关 闭</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style>
|
||||||
|
.gen-key {margin-bottom: 0px !important;}
|
||||||
|
fieldset {border: 1px solid #ccc; color: gray;margin-left: 40px;margin-bottom: 20px;}
|
||||||
|
fieldset label {width: 110px !important;}
|
||||||
|
fieldset .el-form-item__content {margin-left: 110px !important;}
|
||||||
|
.key-view .el-form-item {margin-bottom: 10px !important;}
|
||||||
|
</style>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
const validateSecret = (rule, value, callback) => {
|
|
||||||
if (this.isvDialogFormData.signType === 2) {
|
|
||||||
if (value === '') {
|
|
||||||
callback(new Error('不能为空'))
|
|
||||||
}
|
|
||||||
if (value.length > 200) {
|
|
||||||
callback(new Error('长度不能超过200'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
const validatePubPriKey = (rule, value, callback) => {
|
|
||||||
if (this.isvDialogFormData.signType === 1) {
|
|
||||||
if (value === '') {
|
|
||||||
callback(new Error('不能为空'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
searchFormData: {
|
searchFormData: {
|
||||||
appKey: '',
|
appKey: '',
|
||||||
@@ -195,11 +203,6 @@ export default {
|
|||||||
isvDialogTitle: '新增ISV',
|
isvDialogTitle: '新增ISV',
|
||||||
isvDialogFormData: {
|
isvDialogFormData: {
|
||||||
id: 0,
|
id: 0,
|
||||||
appKey: '',
|
|
||||||
secret: '',
|
|
||||||
pubKey: '',
|
|
||||||
priKey: '',
|
|
||||||
signType: 1,
|
|
||||||
status: 1,
|
status: 1,
|
||||||
roleCode: []
|
roleCode: []
|
||||||
},
|
},
|
||||||
@@ -207,16 +210,17 @@ export default {
|
|||||||
appKey: [
|
appKey: [
|
||||||
{ required: true, message: '不能为空', trigger: 'blur' },
|
{ required: true, message: '不能为空', trigger: 'blur' },
|
||||||
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
|
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
|
||||||
],
|
|
||||||
secret: [
|
|
||||||
{ validator: validateSecret, trigger: 'blur' }
|
|
||||||
],
|
|
||||||
pubKey: [
|
|
||||||
{ validator: validatePubPriKey, trigger: 'blur' }
|
|
||||||
],
|
|
||||||
priKey: [
|
|
||||||
{ validator: validatePubPriKey, trigger: 'blur' }
|
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
isvKeysDialogVisible: false,
|
||||||
|
isvKeysFormData: {
|
||||||
|
appKey: '',
|
||||||
|
secret: '',
|
||||||
|
publicKeyIsv: '',
|
||||||
|
privateKeyIsv: '',
|
||||||
|
publicKeyPlatform: '',
|
||||||
|
privateKeyPlatform: '',
|
||||||
|
signType: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -237,16 +241,12 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShowSecret: function(row) {
|
onShowKeys: function(row) {
|
||||||
this.$alert(row.secret, 'secret')
|
this.post('isv.keys.get', { appKey: row.appKey }, function(resp) {
|
||||||
},
|
this.isvKeysDialogVisible = true
|
||||||
onShowPriPubKey: function(row) {
|
this.$nextTick(() => {
|
||||||
const pubKey = row.pubKey
|
Object.assign(this.isvKeysFormData, resp.data)
|
||||||
const priKey = row.priKey
|
})
|
||||||
const content = '<div>公钥:<textarea style="width: 380px;height: 100px;" readonly="readonly">' + pubKey + '</textarea><br>' +
|
|
||||||
'私钥:<textarea style="width: 380px;height: 100px;" readonly="readonly">' + priKey + '</textarea></div>'
|
|
||||||
this.$alert(content, '公私钥', {
|
|
||||||
dangerouslyUseHTMLString: true
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onSearchTable: function() {
|
onSearchTable: function() {
|
||||||
@@ -268,6 +268,9 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
onKeysUpdate: function(row) {
|
||||||
|
this.$router.push({ path: `keys?appKey=${row.appKey}` })
|
||||||
|
},
|
||||||
onSizeChange: function(size) {
|
onSizeChange: function(size) {
|
||||||
this.searchFormData.pageSize = size
|
this.searchFormData.pageSize = size
|
||||||
this.loadTable()
|
this.loadTable()
|
||||||
@@ -277,9 +280,11 @@ export default {
|
|||||||
this.loadTable()
|
this.loadTable()
|
||||||
},
|
},
|
||||||
onAdd: function() {
|
onAdd: function() {
|
||||||
this.isvDialogFormData.id = 0
|
|
||||||
this.isvDialogTitle = '新增ISV'
|
this.isvDialogTitle = '新增ISV'
|
||||||
this.isvDialogVisible = true
|
this.isvDialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.isvDialogFormData.id = 0
|
||||||
|
})
|
||||||
},
|
},
|
||||||
onIsvDialogSave: function() {
|
onIsvDialogSave: function() {
|
||||||
const that = this
|
const that = this
|
||||||
@@ -294,8 +299,12 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onIsvDialogClose: function() {
|
onIsvDialogClose: function() {
|
||||||
this.$refs.isvForm.resetFields()
|
this.resetForm('isvForm')
|
||||||
this.isvDialogVisible = false
|
this.isvDialogFormData.status = 1
|
||||||
|
this.isvDialogFormData.roleCode = []
|
||||||
|
},
|
||||||
|
selfLabel: function(lab) {
|
||||||
|
return '★ ' + lab
|
||||||
},
|
},
|
||||||
roleRender: function(row) {
|
roleRender: function(row) {
|
||||||
const html = []
|
const html = []
|
||||||
@@ -305,27 +314,8 @@ export default {
|
|||||||
}
|
}
|
||||||
return html.join(', ')
|
return html.join(', ')
|
||||||
},
|
},
|
||||||
onDataGen: function() {
|
showKeys: function() {
|
||||||
this.post('isv.form.gen', {}, function(resp) {
|
return this.isvKeysFormData.signType === 1
|
||||||
const data = resp.data
|
|
||||||
// 如果是新增状态
|
|
||||||
if (this.isvDialogFormData.id === 0) {
|
|
||||||
Object.assign(this.isvDialogFormData, data)
|
|
||||||
} else {
|
|
||||||
const signType = this.isvDialogFormData.signType
|
|
||||||
// RSA2
|
|
||||||
if (signType === 1) {
|
|
||||||
Object.assign(this.isvDialogFormData, {
|
|
||||||
pubKey: data.pubKey,
|
|
||||||
priKey: data.priKey
|
|
||||||
})
|
|
||||||
} else if (signType === 2) {
|
|
||||||
Object.assign(this.isvDialogFormData, {
|
|
||||||
secret: data.secret
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
172
sop-admin/sop-admin-vue/src/views/isv/keys.vue
Normal file
172
sop-admin/sop-admin-vue/src/views/isv/keys.vue
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-button class="el-icon-back" type="text" @click="onBack">返回</el-button>
|
||||||
|
<el-form
|
||||||
|
ref="isvKeysForm"
|
||||||
|
:rules="rulesIsvKeysForm"
|
||||||
|
:model="isvKeysFormData"
|
||||||
|
label-width="160px"
|
||||||
|
size="mini"
|
||||||
|
style="width: 700px;"
|
||||||
|
>
|
||||||
|
<el-form-item label="">
|
||||||
|
<el-alert
|
||||||
|
title="带 ★ 的分配给开发者"
|
||||||
|
type="warning"
|
||||||
|
:closable="false"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="selfLabel('appKey')">
|
||||||
|
<div>{{ isvKeysFormData.appKey }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="签名方式">
|
||||||
|
<el-radio-group v-model="isvKeysFormData.signType">
|
||||||
|
<el-radio :label="1" name="status">RSA2</el-radio>
|
||||||
|
<el-radio :label="2" name="status">MD5</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-show="showKeys()" label="秘钥格式">
|
||||||
|
<el-radio-group v-model="isvKeysFormData.keyFormat">
|
||||||
|
<el-radio :label="1" name="keyFormat">PKCS8(JAVA适用)</el-radio>
|
||||||
|
<el-radio :label="2" name="keyFormat">PKCS1(非JAVA适用)</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-show="isvKeysFormData.signType === 2" prop="secret" :label="selfLabel('secret')">
|
||||||
|
<el-input v-model="isvKeysFormData.secret" /> <el-button type="text" @click="onGenSecret">重新生成</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<fieldset v-show="showKeys()">
|
||||||
|
<legend>ISV公私钥</legend>
|
||||||
|
<el-form-item class="gen-key">
|
||||||
|
<el-button type="text" @click="onGenKeysIsv">重新生成</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="publicKeyIsv" label="ISV公钥">
|
||||||
|
<el-input v-model="isvKeysFormData.publicKeyIsv" type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="privateKeyIsv" :label="selfLabel('ISV私钥')">
|
||||||
|
<el-input v-model="isvKeysFormData.privateKeyIsv" type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset v-show="showKeys()">
|
||||||
|
<legend>平台公私钥</legend>
|
||||||
|
<el-form-item class="gen-key">
|
||||||
|
<el-button type="text" @click="onGenKeysPlatform">重新生成</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="publicKeyPlatform" :label="selfLabel('平台公钥')">
|
||||||
|
<el-input v-model="isvKeysFormData.publicKeyPlatform" type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="privateKeyPlatform" label="平台私钥">
|
||||||
|
<el-input v-model="isvKeysFormData.privateKeyPlatform" type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
</fieldset>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="onSubmit">保存</el-button>
|
||||||
|
<el-button @click="onBack">取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style>
|
||||||
|
.gen-key {margin-bottom: 0px !important;}
|
||||||
|
fieldset {border: 1px solid #ccc; color: gray;margin-left: 40px;margin-bottom: 20px;}
|
||||||
|
fieldset label {width: 110px !important;}
|
||||||
|
fieldset .el-form-item__content {margin-left: 110px !important;}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
const validateSecret = (rule, value, callback) => {
|
||||||
|
if (this.isvKeysFormData.signType === 2) {
|
||||||
|
if (value === '') {
|
||||||
|
callback(new Error('不能为空'))
|
||||||
|
}
|
||||||
|
if (value.length > 200) {
|
||||||
|
callback(new Error('长度不能超过200'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
const validatePubPriKey = (rule, value, callback) => {
|
||||||
|
if (this.isvKeysFormData.signType === 1) {
|
||||||
|
if (value === '') {
|
||||||
|
callback(new Error('不能为空'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
isvKeysFormData: {
|
||||||
|
appKey: '',
|
||||||
|
secret: '',
|
||||||
|
keyFormat: 1,
|
||||||
|
publicKeyIsv: '',
|
||||||
|
privateKeyIsv: '',
|
||||||
|
publicKeyPlatform: '',
|
||||||
|
privateKeyPlatform: '',
|
||||||
|
signType: 1
|
||||||
|
},
|
||||||
|
rulesIsvKeysForm: {
|
||||||
|
secret: [
|
||||||
|
{ validator: validateSecret, trigger: 'blur' }
|
||||||
|
],
|
||||||
|
publicKeyIsv: [
|
||||||
|
{ validator: validatePubPriKey, trigger: 'blur' }
|
||||||
|
],
|
||||||
|
privateKeyIsv: [
|
||||||
|
{ validator: validatePubPriKey, trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
const query = this.$route.query
|
||||||
|
this.isvKeysFormData.appKey = query.appKey
|
||||||
|
this.loadForm()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadForm: function() {
|
||||||
|
this.post('isv.keys.get', { appKey: this.isvKeysFormData.appKey }, function(resp) {
|
||||||
|
Object.assign(this.isvKeysFormData, resp.data)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
selfLabel: function(lab) {
|
||||||
|
return '★ ' + lab
|
||||||
|
},
|
||||||
|
onSubmit: function() {
|
||||||
|
this.$refs.isvKeysForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.post('isv.keys.update', this.isvKeysFormData, function() {
|
||||||
|
this.tip('保存成功')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onBack: function() {
|
||||||
|
this.$router.push({ path: 'list' })
|
||||||
|
},
|
||||||
|
onGenKeysPlatform: function() {
|
||||||
|
this.post('isv.keys.gen', {}, function(resp) {
|
||||||
|
this.tip('生成公私钥成功')
|
||||||
|
const data = resp.data
|
||||||
|
this.isvKeysFormData.publicKeyPlatform = data.publicKey
|
||||||
|
this.isvKeysFormData.privateKeyPlatform = data.privateKey
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onGenKeysIsv: function() {
|
||||||
|
this.post('isv.keys.gen', { keyFormat: this.isvKeysFormData.keyFormat }, function(resp) {
|
||||||
|
this.tip('生成公私钥成功')
|
||||||
|
const data = resp.data
|
||||||
|
this.isvKeysFormData.publicKeyIsv = data.publicKey
|
||||||
|
this.isvKeysFormData.privateKeyIsv = data.privateKey
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onGenSecret: function() {
|
||||||
|
this.post('isv.secret.gen', {}, function(resp) {
|
||||||
|
this.isvKeysFormData.secret = resp.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
showKeys: function() {
|
||||||
|
return this.isvKeysFormData.signType === 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@@ -231,7 +231,18 @@
|
|||||||
</el-container>
|
</el-container>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style>
|
||||||
|
.custom-tree-node {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
.el-input.is-disabled .el-input__inner {color: #909399;}
|
||||||
|
.el-radio__input.is-disabled+span.el-radio__label {color: #909399;}
|
||||||
|
</style>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@@ -425,6 +436,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLimitDialogClose: function() {
|
onLimitDialogClose: function() {
|
||||||
this.resetForm('limitDialogForm')
|
this.resetForm('limitDialogForm')
|
||||||
|
this.limitDialogFormData.limitStatus = 0
|
||||||
},
|
},
|
||||||
infoRender: function(row) {
|
infoRender: function(row) {
|
||||||
const html = []
|
const html = []
|
||||||
|
Reference in New Issue
Block a user