This commit is contained in:
liulu 2024-10-28 11:32:18 +08:00
parent e59811ced4
commit 17356d0314
76 changed files with 3304 additions and 135 deletions

View File

@ -37,6 +37,16 @@
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
</dependency>
</dependencies>

View File

@ -0,0 +1,38 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author liulu
* @since 2024/10/16
*/
@Getter
@AllArgsConstructor
public enum ApiFunEnum {
sym_enc(ApiGroupEnum.SYM_API,"sym_enc", "对称加密"),
sym_dec(ApiGroupEnum.ASYM_API,"sym_dec", "对称解密"),
cal_hmac(ApiGroupEnum.SYM_API,"cal_hmac", "计算Hmac"),
check_hmac(ApiGroupEnum.ASYM_API,"check_hmac", "验证Hmac"),
cal_mac(ApiGroupEnum.SYM_API,"cal_mac", "计算mac"),
check_mac(ApiGroupEnum.ASYM_API,"check_mac", "验证mac"),
gen_random(ApiGroupEnum.SYM_API,"gen_random", "生成随机数"),
asym_enc(ApiGroupEnum.ASYM_API,"asym_enc", "非对称加密"),
asym_dec(ApiGroupEnum.ASYM_API,"asym_dec", "非对称解密"),
sign_raw(ApiGroupEnum.ASYM_API,"sign_raw", "RAW签名"),
verify_raw(ApiGroupEnum.ASYM_API,"verify_raw", "RAW验签"),
sign_p1(ApiGroupEnum.ASYM_API,"sign_p1", "P1签名"),
verify_p1(ApiGroupEnum.ASYM_API,"verify_p1", "P1验签"),
sign_P7Attach(ApiGroupEnum.ASYM_API,"sign_P7Attach", "P7 Attach签名"),
verify_P7Attach(ApiGroupEnum.ASYM_API,"verify_P7Attach", "P7 Attach验签"),
sign_P7Detach(ApiGroupEnum.ASYM_API,"sign_P7Detach", "P7 Detach签名"),
verify_P7Detach(ApiGroupEnum.ASYM_API,"verify_P7Detach", "P7 Detach验签"),
;
private final ApiGroupEnum group;
private final String code;
private final String name;
}

View File

@ -0,0 +1,34 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author liulu
* @since 2024/10/16
*/
@Getter
@AllArgsConstructor
public enum ApiGroupEnum {
SYM_API("sym_api", "对称密钥计算接口"),
ASYM_API("asym_api", "非对称密钥计算接口"),
;
private final String code;
private final String name;
public static ApiGroupEnum of(String code) {
if (code == null || code.trim().isEmpty()) {
return null;
}
return Arrays.stream(ApiGroupEnum.values())
.filter(it -> Objects.equals(it.code, code))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,37 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author liulu
* @since 2024/10/16
*/
@Getter
@AllArgsConstructor
public enum EnableStatus {
ENABLED("enabled", "启用"),
DISABLED("disabled", "停用"),
;
private final String code;
private final String desc;
public static EnableStatus of(String code) {
if (code == null || code.trim().isEmpty()) {
return null;
}
return Arrays.stream(EnableStatus.values())
.filter(it -> Objects.equals(it.code, code))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,35 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author liulu
* @since 2024/10/22
*/
@Getter
@AllArgsConstructor
public enum KeyAlg {
SM4(KeyCategory.SYM_KEY, "SM4", "国密SM4"),
SM2(KeyCategory.ASYM_KEY, "SM2", "国密SM2"),
;
private final KeyCategory category;
private final String code;
private final String desc;
public static KeyAlg of(String code) {
if (code == null || code.trim().isEmpty()) {
return null;
}
return Arrays.stream(KeyAlg.values())
.filter(it -> Objects.equals(it.code, code))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,38 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author liulu
* @since 2024/10/22
*/
@Getter
@AllArgsConstructor
public enum KeyCategory {
// 对称密钥
SYM_KEY("sym_key", "对称密钥"),
// 非对称密钥
ASYM_KEY("asym_key", "非对称密钥"),
;
private final String code;
private final String desc;
public static KeyCategory of(String code) {
if (code == null || code.trim().isEmpty()) {
return null;
}
return Arrays.stream(KeyCategory.values())
.filter(it -> Objects.equals(it.code, code))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,36 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author liulu
* @since 2024/10/23
*/
@Getter
@AllArgsConstructor
public enum KeyStatus {
ENABLED("enabled", "启用中"),
DISABLED("disabled", "已禁用"),
ARCHIVED("archived", "已归档"),
DELETED("deleted", "已销毁"),
;
private final String code;
private final String desc;
public static KeyStatus of(String code) {
if (code == null || code.trim().isEmpty()) {
return null;
}
return Arrays.stream(KeyStatus.values())
.filter(it -> Objects.equals(it.code, code))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,62 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author liulu
* @since 2024/10/22
*/
@Getter
@AllArgsConstructor
public enum KeyUsage {
// 加密解密
ENCRYPT_DECRYPT("encrypt_decrypt", "加密解密", 1),
// 签名验签
SIGN_VERIFY("sign_verify", "签名验签", 2),
// 计算HMac
HMAC("hmac", "计算HMac", 4),
// 计算Mac
MAC("mac", "计算Mac", 8),
;
private final String code;
private final String desc;
private final int value;
public static int getStatus(List<String> codes) {
if (CollectionUtils.isEmpty(codes)) {
return 0;
}
return codes.stream()
.map(String::toUpperCase)
.map(KeyUsage::valueOf)
.mapToInt(KeyUsage::getValue)
.reduce(0, (l, r) -> l | r);
}
public static List<KeyUsage> getUsage(int status) {
if (status == 0) {
return Collections.emptyList();
}
return Arrays.stream(KeyUsage.values())
.filter(it -> hasUsage(status, it))
.collect(Collectors.toList());
}
public static boolean hasUsage(int nowUsage, KeyUsage usage) {
return (nowUsage & usage.value) == 1;
}
}

View File

@ -0,0 +1,34 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author liulu
* @since 2024/10/17
*/
@Getter
@AllArgsConstructor
public enum ManufacturerEnum {
SUNYARD("sunyard", "信雅达"),
;
private final String code;
private final String name;
public static ManufacturerEnum of(String code) {
if (code == null || code.trim().isEmpty()) {
return null;
}
return Arrays.stream(ManufacturerEnum.values())
.filter(it -> Objects.equals(it.code, code))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,35 @@
package com.sunyard.chsm.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author liulu
* @since 2024/10/17
*/
@Getter
@AllArgsConstructor
public enum ManufacturerModelEnum {
enc001(ManufacturerEnum.SUNYARD, "enc001", "服务器密码机enc001"),
;
private final ManufacturerEnum manufacturer;
private final String model;
private final String name;
public static ManufacturerModelEnum of(String code) {
if (code == null || code.trim().isEmpty()) {
return null;
}
return Arrays.stream(ManufacturerModelEnum.values())
.filter(it -> Objects.equals(it.model, code))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,13 @@
package com.sunyard.chsm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.chsm.model.entity.CryptoServiceApi;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liulu
* @since 2024/10/15
*/
@Mapper
public interface CryptoServiceApiMapper extends BaseMapper<CryptoServiceApi> {
}

View File

@ -0,0 +1,13 @@
package com.sunyard.chsm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.chsm.model.entity.CryptoService;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liulu
* @since 2024/10/15
*/
@Mapper
public interface CryptoServiceMapper extends BaseMapper<CryptoService> {
}

View File

@ -0,0 +1,13 @@
package com.sunyard.chsm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.chsm.model.entity.KeyInfo;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liulu
* @since 2024/10/22
*/
@Mapper
public interface KeyInfoMapper extends BaseMapper<KeyInfo> {
}

View File

@ -0,0 +1,13 @@
package com.sunyard.chsm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.chsm.model.entity.KeyTemplate;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liulu
* @since 2024/10/22
*/
@Mapper
public interface KeyTemplateMapper extends BaseMapper<KeyTemplate> {
}

View File

@ -0,0 +1,13 @@
package com.sunyard.chsm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.chsm.model.entity.DeviceGroup;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liulu
* @since 2024/10/17
*/
@Mapper
public interface SpDeviceGroupMapper extends BaseMapper<DeviceGroup> {
}

View File

@ -0,0 +1,13 @@
package com.sunyard.chsm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.chsm.model.entity.Device;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liulu
* @since 2024/10/17
*/
@Mapper
public interface SpDeviceMapper extends BaseMapper<Device> {
}

View File

@ -0,0 +1,13 @@
package com.sunyard.chsm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.chsm.model.entity.KeyRecord;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liulu
* @since 2024/10/22
*/
@Mapper
public interface SpKeyRecordMapper extends BaseMapper<KeyRecord> {
}

View File

@ -0,0 +1,43 @@
package com.sunyard.chsm.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* @author liulu
* @since 2024/10/16
*/
@Getter
@NoArgsConstructor
public class PageQuery {
public static final int MAX_PAGE_SIZE = 200;
/**
* 当前页
*/
private int pageNumber = 1;
/**
* 每页大小
*/
private int pageSize = 10;
public PageQuery(int pageNum, int pageSize) {
this.pageNumber = pageNum;
this.pageSize = pageSize;
}
public void setPageNumber(int pageNum) {
this.pageNumber = Math.max(1, pageNum);
}
public void setPageSize(int pageSize) {
this.pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, pageSize));
}
public int getOffset() {
return pageSize * (pageNumber - 1);
}
}

View File

@ -0,0 +1,87 @@
package com.sunyard.chsm.model;
import lombok.Data;
/**
* @author liulu
* @since 2024/10/17
*/
@Data
public class R<T> {
/**
* 成功标志
*/
private boolean success;
/**
* 失败消息
*/
private String message;
/**
* 返回代码 200-代表成功
*/
private Integer code;
/**
* 时间戳
*/
private long timestamp = System.currentTimeMillis();
/**
* 结果对象
*/
private T result;
public static <T> R<T> ok() {
R<T> r = new R<>();
r.setSuccess(true);
r.setMessage("success");
r.setCode(200);
return r;
}
public static <T> R<T> ok(String msg) {
R<T> r = new R<>();
r.setSuccess(true);
r.setMessage(msg);
r.setCode(200);
return r;
}
public static <T> R<T> data(T value) {
R<T> r = new R<>();
r.setSuccess(true);
r.setResult(value);
r.setCode(200);
return r;
}
public static <T> R<T> data(T value, String msg) {
R<T> r = new R<>();
r.setSuccess(true);
r.setResult(value);
r.setMessage(msg);
r.setCode(200);
return r;
}
public static <T> R<T> error(String msg) {
R<T> r = new R<>();
r.setSuccess(false);
r.setMessage(msg);
r.setCode(500);
return r;
}
public static <T> R<T> error(int code, String msg) {
R<T> r = new R<>();
r.setSuccess(false);
r.setMessage(msg);
r.setCode(code);
return r;
}
}

View File

@ -0,0 +1,29 @@
package com.sunyard.chsm.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/15
*/
@Data
@TableName("sp_crypto_service")
public class CryptoService {
private Long id;
private String name;
private Long deviceGroupId;
private String deviceGroupName;
private String status;
private Long creatorId;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,27 @@
package com.sunyard.chsm.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/15
*/
@Data
@TableName("sp_crypto_service_api")
public class CryptoServiceApi {
private Long id;
private Long cryptoServiceId;
private String apiGroup;
private String apiCode;
private String apiName;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,34 @@
package com.sunyard.chsm.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/17
*/
@Data
@TableName("sp_device")
public class Device {
private Long id;
private String name;
private String serviceIp;
private Integer servicePort;
private String manageIp;
private Integer managePort;
private String manufacturer;
private String manufacturerModel;
private String accessCredentials;
private Long groupId;
private String groupName;
private Integer weight;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,23 @@
package com.sunyard.chsm.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/17
*/
@Data
@TableName("sp_device_group")
public class DeviceGroup {
private Long id;
private String name;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,34 @@
package com.sunyard.chsm.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/22
*/
@Data
@TableName("sp_key_info")
public class KeyInfo {
private Long id;
private Long applicationId;
private Long keyTemplateId;
private String code;
private String keyType;
private String keyAlg;
private Integer keyLength;
private Integer keyUsage;
private String checkAlg;
private String checkValue;
private String status;
private LocalDateTime effectiveTime;
private LocalDateTime expiredTime;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,31 @@
package com.sunyard.chsm.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/22
*/
@Data
@TableName("sp_key_record")
public class KeyRecord {
private Long id;
private Long keyId;
private String keyIndex;
private String keyData;
private String pubKey;
private String checkAlg;
private String checkValue;
private LocalDateTime effectiveTime;
private LocalDateTime expiredTime;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,34 @@
package com.sunyard.chsm.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/22
*/
@Data
@TableName("sp_key_template")
public class KeyTemplate {
private Long id;
private String code;
private String name;
private String keyType;
private String keyAlg;
private Integer keyLength;
private Integer keyUsage;
private String checkAlg;
private Integer validTime;
private String validUnit;
private Integer startAfterCreateTime;
private String startAfterCreateUnit;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,94 @@
package com.sunyard.chsm.sdf;
import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.sdf.model.EccPriKey;
import com.sunyard.chsm.sdf.model.EccPubKey;
import lombok.SneakyThrows;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.util.BigIntegers;
import org.springframework.stereotype.Service;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
/**
* @author liulu
* @since 2024/10/23
*/
@Service
public class BCSdfApiService implements SdfApiService {
@Override
public byte[] generateRandom(int len) {
byte[] res = new byte[len];
new SecureRandom().nextBytes(res);
return res;
}
@SneakyThrows
@Override
public EccKey genKeyPairEcc() {
// 获取SM2参数
X9ECParameters sm2Params = GMNamedCurves.getByOID(GMObjectIdentifiers.sm2p256v1);
ECParameterSpec sm2Spec = new ECParameterSpec(sm2Params.getCurve(), sm2Params.getG(), sm2Params.getN(), sm2Params.getH());
// 创建密钥对生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME);
keyPairGenerator.initialize(sm2Spec);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
BCECPublicKey pubKey = (BCECPublicKey) keyPair.getPublic();
BCECPrivateKey priKey = (BCECPrivateKey) keyPair.getPrivate();
byte[] x = pubKey.getQ().getXCoord().getEncoded();
byte[] y = pubKey.getQ().getYCoord().getEncoded();
byte[] d = BigIntegers.asUnsignedByteArray(64, priKey.getD());
return new EccKey(new EccPubKey(256, x, y), new EccPriKey(256, d));
}
@Override
public EccKey genEccKeyPairAndEncByKek() {
return null;
}
@Override
public byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData) {
return new byte[0];
}
@Override
public byte[] hmac(byte[] key, byte[] srcData) {
KeyParameter keyParameter = new KeyParameter(key);
SM3Digest digest = new SM3Digest();
HMac mac = new HMac(digest);
mac.init(keyParameter);
mac.update(srcData, 0, srcData.length);
byte[] result = new byte[mac.getMacSize()];
mac.doFinal(result, 0);
return result;
}
@Override
public byte[] hash(byte[] pucData) {
SM3Digest digest = new SM3Digest();
digest.update(pucData, 0, pucData.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
return hash;
}
}

View File

@ -0,0 +1,57 @@
package com.sunyard.chsm.sdf;
import com.sunyard.chsm.sdf.model.EccKey;
/**
* @author liulu
* @since 2024/10/23
*/
public interface SdfApiService {
/**
* 产生随机数
*
* @param len 随机数长度
* @return 返回随机数
*/
byte[] generateRandom(int len);
/**
* 产生ECC密钥对并输出
*
* @return pubKey 返回公钥 | priKey 返回私钥
*/
EccKey genKeyPairEcc();
/**
* 产生ECC加密密钥对并使用kek加密私钥输出
*
* @return pubKey 返回公钥 | priKey 返回私钥
*/
EccKey genEccKeyPairAndEncByKek();
/**
* 计算MAC
*
* @param symKey 用户指定的密钥
* @param pucIv 缓冲区指针用于存放输入和返回的IV数据
* @param pucData 缓冲区指针用于存放输入的数据明文
* @return pucEncData 返回MAC值 | puiLength 返回MAC值长度
*/
byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData);
byte[] hmac(byte[] key, byte[] srcData);
/**
* 多包杂凑运算
*
* @param pucData 缓冲区指针用于存放输入的数据明文
* @return hash值
*/
byte[] hash(byte[] pucData);
}

View File

@ -0,0 +1,23 @@
package com.sunyard.chsm.sdf.model;
import lombok.Data;
/**
* @author liulu
* @version V1.0
* @since 2022/10/11
*/
@Data
public class DeviceInfo {
private String issuerName;
private String deviceName;
private String deviceSerial;
private int deviceVersion;
private int standardVersion;
private int[] asymAlgAbility;
private int symAlgAbility;
private int hashAlgAbility;
private int bufferSize;
}

View File

@ -0,0 +1,44 @@
package com.sunyard.chsm.sdf.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liulu
* @version V1.0
* @since 2022/11/11
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EccCipher {
// X 分量
private byte[] x;
// Y 分量
private byte[] y;
// 明文的 SM3 杂凑值
private byte[] M;
// 密文数据长度
private int L;
// 密文数据
private byte[] C;
public byte[] getC1C3C2Bytes() {
int xLen = x.length;
int yLen = y.length;
int mLen = M.length;
byte[] rawData = new byte[xLen + yLen + mLen + L];
System.arraycopy(x, 0, rawData, 0, xLen);
System.arraycopy(y, 0, rawData, xLen, yLen);
System.arraycopy(M, 0, rawData, xLen + yLen, mLen);
System.arraycopy(C, 0, rawData, xLen + yLen + mLen, L);
return rawData;
}
}

View File

@ -0,0 +1,24 @@
package com.sunyard.chsm.sdf.model;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liulu
* @version V1.0
* @since 2022/11/11
*/
@Data
@NoArgsConstructor
public class EccKey {
private EccPubKey pubKey;
private EccPriKey priKey;
public EccKey(EccPubKey pubKey, EccPriKey priKey) {
this.pubKey = pubKey;
this.priKey = priKey;
}
}

View File

@ -0,0 +1,22 @@
package com.sunyard.chsm.sdf.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liulu
* @version V1.0
* @since 2022/11/11
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EccPriKey {
//
private int bits;
//
private byte[] D;
}

View File

@ -0,0 +1,31 @@
package com.sunyard.chsm.sdf.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liulu
* @version V1.0
* @since 2022/11/11
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EccPubKey {
//
private int bits;
// x
private byte[] x;
// y
private byte[] y;
public byte[] getPubKeyBytes() {
byte[] rawKey = new byte[x.length + y.length];
System.arraycopy(x, 0, rawKey, 0, x.length);
System.arraycopy(y, 0, rawKey, x.length, y.length);
return rawKey;
}
}

View File

@ -0,0 +1,31 @@
package com.sunyard.chsm.sdf.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liulu
* @version V1.0
* @since 2022/11/11
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EccSignature {
// 签名的 r 部分
private byte[] r;
// 签名的 s 部分
private byte[] s;
public byte[] getRawSignBytes() {
byte[] signData = new byte[r.length + s.length];
System.arraycopy(r, 0, signData, 0, r.length);
System.arraycopy(s, 0, signData, r.length, s.length);
return signData;
}
}

View File

@ -1,4 +1,4 @@
package com.sunyard.utils;
package com.sunyard.chsm.utils;
/**
* @author liulu

View File

@ -1,4 +1,4 @@
package com.sunyard.utils;
package com.sunyard.chsm.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;

View File

@ -1,4 +1,4 @@
package com.sunyard.utils;
package com.sunyard.chsm.utils;
/**
* @author liulu

View File

@ -46,16 +46,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<!-- <version>${bouncycastle.version}</version>-->
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<!-- <version>${bouncycastle.version}</version>-->
</dependency>
<dependency>
<groupId>com.dm</groupId>
<artifactId>DmJdbcDriver</artifactId>
@ -140,5 +130,19 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,5 +1,6 @@
package com.sunyard;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@ -9,14 +10,15 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* @author liulu
* @since 2024/10/25
*/
@SpringBootApplication
//@ComponentScan(basePackages={"com.sunyard"})
@EnableScheduling
@Slf4j
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class WebManageApp {
public static void main(String[] args) {
SpringApplication.run(WebManageApp.class, args);
log.info("---------------------WebManageApp 启动完成-------------------");
}
}

View File

@ -0,0 +1,8 @@
package com.sunyard.chsm.controller;
/**
* @author liulu
* @since 2024/10/23
*/
public class AsymKeyController {
}

View File

@ -0,0 +1,120 @@
package com.sunyard.chsm.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.ApiGroupDTO;
import com.sunyard.chsm.dto.CryptoServiceDTO;
import com.sunyard.chsm.enums.ApiFunEnum;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.service.CryptoServiceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 密码服务管理接口
*
* @author liulu
* @since 2024/10/15
*/
@Slf4j
@RestController
@RequestMapping("/crypto/service")
public class CryptoServiceController {
@Resource
private CryptoServiceService cryptoServiceService;
/**
* 查询密码服务接口分组列表
*
* @return
*/
@GetMapping("/apiGroupList")
public R<List<ApiGroupDTO>> getApiGroupList() {
List<ApiGroupDTO> res = Arrays.stream(ApiFunEnum.values())
.collect(Collectors.groupingBy(ApiFunEnum::getGroup))
.entrySet().stream()
.map(it -> {
ApiGroupDTO group = new ApiGroupDTO();
group.setGroupCode(it.getKey().getCode());
group.setGroupName(it.getKey().getName());
group.setApiList(it.getValue().stream().map(it2 -> {
ApiGroupDTO.Api api = new ApiGroupDTO.Api();
api.setCode(it2.getCode());
api.setName(it2.getName());
return api;
})
.collect(Collectors.toList()));
return group;
})
.collect(Collectors.toList());
return R.data(res);
}
/**
* 分页查询密码服务列表
*
* @param query 查询条件
* @return 密码服务列表
*/
@GetMapping("/pageList")
public R<Page<CryptoServiceDTO.View>> servicePageList(CryptoServiceDTO.Query query) {
Page<CryptoServiceDTO.View> page = cryptoServiceService.selectPageList(query);
return R.data(page);
}
/**
* 创建密码服务
*
* @param save 参数
* @return 密码服务id
*/
@PostMapping
public R<String> saveService(@Valid @RequestBody CryptoServiceDTO.Save save) {
Long id = cryptoServiceService.save(save);
return R.data(String.valueOf(id));
}
/**
* 修改密码服务
*
* @param update 参数
* @return 密码服务id
*/
@PutMapping
public R<Void> updateService(@Valid @RequestBody CryptoServiceDTO.Save update) {
Assert.notNull(update.getId(), "密码服务id不能为空");
cryptoServiceService.update(update);
return R.ok();
}
/**
* 删除密码服务
*
* @param id 密码服务id
* @return
*/
@DeleteMapping
public R<Void> deleteService(Long id) {
Assert.notNull(id, "密码服务id不能为空");
cryptoServiceService.delete(id);
return R.ok();
}
}

View File

@ -0,0 +1,143 @@
package com.sunyard.chsm.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.DeviceDTO;
import com.sunyard.chsm.dto.ManufacturersDeviceDTO;
import com.sunyard.chsm.enums.ManufacturerModelEnum;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 密码机管理接口
*
* @author liulu
* @since 2024/10/15
*/
@Slf4j
@RestController("sp_DeviceController")
@RequestMapping("/device")
public class DeviceController {
@Resource
private DeviceService deviceService;
/**
* 分页查询密码设备列表
*
* @param query 查询条件
* @return 分页列表
*/
@GetMapping("/pageList")
public R<Page<DeviceDTO.View>> servicePageList(DeviceDTO.Query query) {
Page<DeviceDTO.View> page = deviceService.selectPageList(query);
return R.data(page);
}
/**
* 查询未分组设备列表
*
* @return 列表
*/
@GetMapping("/ungrouped/list")
public R<List<DeviceDTO.View>> getUngroupedList() {
List<DeviceDTO.View> res = deviceService.getUngroupedList();
return R.data(res);
}
/**
* 查询设备详情
*
* @param id id
* @return 详情
*/
@GetMapping("/detail")
public R<DeviceDTO.Detail> getById(Long id) {
DeviceDTO.Detail res = deviceService.getDetailById(id);
return R.data(res);
}
/**
* 查询已适配的厂商设备列表
*
* @return 列表
*/
@GetMapping("/adapted/list")
public R<List<ManufacturersDeviceDTO>> getAdaptedList() {
List<ManufacturersDeviceDTO> manufacturers = Arrays.stream(ManufacturerModelEnum.values())
.collect(Collectors.groupingBy(ManufacturerModelEnum::getManufacturer))
.entrySet().stream()
.map(it -> {
ManufacturersDeviceDTO adaptedDevices = new ManufacturersDeviceDTO();
adaptedDevices.setCode(it.getKey().getCode());
adaptedDevices.setName(it.getKey().getName());
List<ManufacturersDeviceDTO.Model> modelList = it.getValue().stream().map(it2 -> {
ManufacturersDeviceDTO.Model model = new ManufacturersDeviceDTO.Model();
model.setModel(it2.getModel());
model.setName(it2.getName());
return model;
})
.collect(Collectors.toList());
adaptedDevices.setModels(modelList);
return adaptedDevices;
})
.collect(Collectors.toList());
return R.data(manufacturers);
}
/**
* 添加密码设备
*
* @param save 参数
* @return id
*/
@PostMapping
public R<String> save(@Valid @RequestBody DeviceDTO.Save save) {
Long id = deviceService.save(save);
return R.data(String.valueOf(id));
}
/**
* 修改密码设备
*
* @param update 参数
* @return void
*/
@PutMapping
public R<Void> update(@Valid @RequestBody DeviceDTO.Save update) {
deviceService.update(update);
return R.ok();
}
/**
* 删除密码设备
*
* @param id id
* @return void
*/
@DeleteMapping
public R<Void> delete(Long id) {
deviceService.delete(id);
return R.ok();
}
}

View File

@ -0,0 +1,81 @@
package com.sunyard.chsm.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.DeviceGroupDTO;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.service.DeviceGroupService;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/**
* 设备组管理接口
*
* @author liulu
* @since 2024/10/21
*/
@RestController("sp_DeviceGroupController")
@RequestMapping("/device/group")
public class DeviceGroupController {
@Resource
private DeviceGroupService deviceGroupService;
/**
* 分页查询设备组列表
*
* @param query 查询条件
* @return 分页列表
*/
@GetMapping("/pageList")
public R<Page<DeviceGroupDTO.View>> servicePageList(DeviceGroupDTO.Query query) {
Page<DeviceGroupDTO.View> page = deviceGroupService.selectPageList(query);
return R.data(page);
}
/**
* 添加设备组
*
* @param save 参数
* @return id
*/
@PostMapping
public R<String> save(@Valid @RequestBody DeviceGroupDTO.Save save) {
Long id = deviceGroupService.save(save);
return R.data(String.valueOf(id));
}
/**
* 修改设备组
*
* @param update 参数
* @return void
*/
@PutMapping
public R<Void> update(@Valid @RequestBody DeviceGroupDTO.Save update) {
deviceGroupService.update(update);
return R.ok();
}
/**
* 删除设备组
*
* @param id id
* @return void
*/
@DeleteMapping
public R<Void> delete(Long id) {
deviceGroupService.delete(id);
return R.ok();
}
}

View File

@ -0,0 +1,80 @@
package com.sunyard.chsm.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.KeyTemplateDTO;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.service.KeyTemplateService;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/**
* 密钥模版管理接口
* @author liulu
* @since 2024/10/22
*/
@RestController
@RequestMapping("/key/template")
public class KeyTemplateController {
@Resource
private KeyTemplateService keyTemplateService;
/**
* 分页查询密钥模版
*
* @param query 查询条件
* @return 分页列表
*/
@GetMapping("/pageList")
public R<Page<KeyTemplateDTO.View>> servicePageList(KeyTemplateDTO.Query query) {
Page<KeyTemplateDTO.View> page = keyTemplateService.selectPageList(query);
return R.data(page);
}
/**
* 添加密钥模版
*
* @param save 参数
* @return id
*/
@PostMapping
public R<String> save(@Valid @RequestBody KeyTemplateDTO.Save save) {
Long id = keyTemplateService.save(save);
return R.data(String.valueOf(id));
}
/**
* 修改密钥模版
*
* @param update 参数
* @return void
*/
@PutMapping
public R<Void> update(@Valid @RequestBody KeyTemplateDTO.Save update) {
keyTemplateService.update(update);
return R.ok();
}
/**
* 删除密钥模版
*
* @param id id
* @return void
*/
@DeleteMapping
public R<Void> delete(Long id) {
keyTemplateService.delete(id);
return R.ok();
}
}

View File

@ -0,0 +1,41 @@
package com.sunyard.chsm.controller;
import com.sunyard.chsm.dto.KeyInfoDTO;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.service.KeyInfoService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/**
* 对称密钥管理接口
*
* @author liulu
* @since 2024/10/23
*/
@RestController
@RequestMapping("/sym/key")
public class SymKeyController {
@Resource
private KeyInfoService keyInfoService;
/**
* 创建密钥
*
* @param save 参数
* @return id
*/
@PostMapping
public R<String> save(@Valid @RequestBody KeyInfoDTO.Save save) {
Long id = keyInfoService.save(save);
return R.data(String.valueOf(id));
}
}

View File

@ -0,0 +1,39 @@
package com.sunyard.chsm.dto;
import lombok.Data;
import java.util.List;
/**
* @author liulu
* @since 2024/10/16
*/
@Data
public class ApiGroupDTO {
/**
* API分组标识
*/
private String groupCode;
/**
* API分组名称
*/
private String groupName;
/**
* API列表
*/
private List<Api> apiList;
@Data
public static class Api {
/**
* API标识
*/
private String code;
/**
* API名称
*/
private String name;
}
}

View File

@ -0,0 +1,112 @@
package com.sunyard.chsm.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.sunyard.chsm.model.PageQuery;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author liulu
* @since 2024/10/15
*/
public abstract class CryptoServiceDTO {
@EqualsAndHashCode(callSuper = true)
@Data
public static class Query extends PageQuery {
/**
* 密码服务名称
*/
private String name;
}
@Data
public static class Save {
/**
* 密码服务Id
*/
private Long id;
/**
* 密码服务名称
*/
@NotBlank(message = "密码服务名称不能为空")
private String name;
/**
* API功能项
*/
@NotEmpty(message = "API功能不能为空")
private List<String> apiList;
/**
* 设备组id
*/
@NotNull(message = "设备组不能为空")
private Long deviceGroupId;
/**
* 备注
*/
private String remark;
}
@Data
public static class View {
/**
* 密码服务Id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 密码服务名称
*/
private String name;
/**
* 设备组id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long deviceGroupId;
/**
* 设备组名称
*/
private String deviceGroupName;
/**
* 已分配API
*/
private List<String> apiList;
/**
* API 描述
*/
private String apiDesc;
/**
* 密码服务状态
*/
private String status;
/**
* 密码服务状态描述
*/
private String statusDesc;
/**
* 密码服务创建人id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long creatorId;
/**
* 备注
*/
private String remark;
/**
* 密码服务创建时间
*/
private LocalDateTime createTime;
}
}

View File

@ -0,0 +1,143 @@
package com.sunyard.chsm.dto;
import com.sunyard.chsm.model.PageQuery;
import com.sunyard.ssp.common.constant.RegexConstant;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
/**
* @author liulu
* @since 2024/10/18
*/
public abstract class DeviceDTO {
@EqualsAndHashCode(callSuper = true)
@Data
public static class Query extends PageQuery {
/**
* 厂商
*/
private String manufacturers;
/**
* 型号
*/
private String model;
/**
* 名称
*/
private String name;
}
@Data
public static class Save {
private Long id;
/**
* 名称
*/
@NotBlank(message = "名称不能为空")
private String name;
/**
* 厂商
*/
@NotBlank(message = "厂商不能为空")
private String manufacturer;
/**
* 型号
*/
@NotBlank(message = "型号不能为空")
private String manufacturerModel;
/**
* 服务ip
*/
@NotBlank(message = "服务ip不能为空")
@Pattern(regexp = RegexConstant.DEVICE_IPV4, message = "ip格式错误")
private String serviceIp;
/**
* 服务端口
*/
@NotNull(message = "服务端口不能为空")
private Integer servicePort;
/**
* 管理ip
*/
@Pattern(regexp = RegexConstant.DEVICE_IPV4, message = "ip格式错误")
private String manageIp;
/**
* 管理端口
*/
private Integer managePort;
/**
* 访问凭证
*/
private String accessCredentials;
/**
* 备注
*/
@Size(max = 500, message = "备注长度在1-500之间")
private String remark;
}
@Data
public static class View {
private Long id;
/**
* 名称
*/
private String name;
/**
* 厂商
*/
private String manufacturer;
private String manufacturerText;
/**
* 型号
*/
private String manufacturerModel;
private String manufacturerModelText;
/**
* 服务ip
*/
private String serviceIp;
/**
* 服务端口
*/
private Integer servicePort;
/**
* 管理ip
*/
private String manageIp;
/**
* 管理端口
*/
private Integer managePort;
/**
* 访问凭证
*/
private String accessCredentials;
/**
* 备注
*/
private String remark;
private LocalDateTime createTime;
}
@EqualsAndHashCode(callSuper = true)
@Data
public static class Detail extends View {
private Double cpuRate;
private Double memoryRate;
private Double diskRate;
}
}

View File

@ -0,0 +1,66 @@
package com.sunyard.chsm.dto;
import com.sunyard.chsm.model.PageQuery;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author liulu
* @since 2024/10/21
*/
public abstract class DeviceGroupDTO {
@EqualsAndHashCode(callSuper = true)
@Data
public static class Query extends PageQuery {
/**
* 名称
*/
private String name;
}
@Data
public static class View {
private Long id;
/**
* 设备组名称
*/
private String name;
/**
* 密码设备
*/
private String deviceNames;
/**
* 备注
*/
private String remark;
private LocalDateTime createTime;
}
@Data
public static class Save {
private Long id;
/**
* 设备组名称
*/
@NotBlank(message = "设备组名称不能为空")
private String name;
/**
* 密码设备id
*/
private List<Long> deviceIds;
/**
* 备注
*/
private String remark;
}
}

View File

@ -0,0 +1,32 @@
package com.sunyard.chsm.dto;
import lombok.Data;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
/**
* @author liulu
* @since 2024/10/23
*/
public abstract class KeyInfoDTO {
@Data
public static class Save {
private Long applicationId;
/**
* 密钥模版编码
*/
@NotNull(message = "密钥模版不能为空")
private String keyTemplateCode;
/**
* 生成数量
*/
@NotNull(message = "生成数量不能为空")
@Max(value = 100, message = "一次最多生成100个密钥")
private Integer genNumber;
}
}

View File

@ -0,0 +1,113 @@
package com.sunyard.chsm.dto;
import com.sunyard.chsm.model.PageQuery;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author liulu
* @since 2024/10/22
*/
public abstract class KeyTemplateDTO {
@EqualsAndHashCode(callSuper = true)
@Data
public static class Query extends PageQuery {
/**
* 密钥类型
* @see com.sunyard.ssp.web.enums.KeyCategory#getCode()
*/
private String keyType;
}
@Data
public static class View {
private Long id;
private String code;
private String name;
private String keyType;
private String keyTypeText;
private String keyAlg;
private Integer keyLength;
private List<String> keyUsages;
private String keyUsageText;
private Integer validTime;
private String validUnit;
private Integer startAfterCreateTime;
private String startAfterCreateUnit;
private String remark;
private LocalDateTime createTime;
}
@Data
public static class Save {
private Long id;
/**
* 模版编号
*/
@NotBlank(message = "模版编号不能为空")
private String code;
/**
* 模版名称
*/
@NotBlank(message = "模版名称不能为空")
private String name;
/**
* 密钥类型
* @see com.sunyard.ssp.web.enums.KeyCategory#getCode()
*/
@NotBlank(message = "密钥类型不能为空")
private String keyType;
/**
* 密钥算法
* @see com.sunyard.ssp.web.enums.KeyAlg#getCode()
*/
@NotBlank(message = "密钥算法不能为空")
private String keyAlg;
/**
* 密钥长度
*/
@NotNull(message = "密钥长度不能为空")
private Integer keyLength;
/**
* 密钥用途
* @see com.sunyard.ssp.web.enums.KeyUsage#getCode()
*/
@NotEmpty(message = "密钥用途不能为空")
private List<String> keyUsages;
/**
* 密钥有效期
*/
@NotNull(message = "密钥有效期不能为空")
private Integer validTime;
/**
* 密钥有效期时间单位 YEARS, MONTHS, DAYS
*/
@NotBlank(message = "密钥有效期时间单位不能为空")
private String validUnit;
/**
* 创建后多久生效
*/
@NotNull(message = "创建后多久生效不能为空")
private Integer startAfterCreateTime;
/**
* 创建后多久生效时间单位 MONTHS, DAYS, HOURS
*/
@NotBlank(message = "创建后多久生效时间单位不能为空")
private String startAfterCreateUnit;
private String remark;
}
}

View File

@ -0,0 +1,40 @@
package com.sunyard.chsm.dto;
import lombok.Data;
import java.util.List;
/**
* @author liulu
* @since 2024/10/17
*/
@Data
public class ManufacturersDeviceDTO {
/**
* 厂商编码
*/
private String code;
/**
* 厂商名称
*/
private String name;
/**
* 厂商设备型号
*/
private List<Model> models;
@Data
public static class Model {
/**
* 设备型号
*/
private String model;
/**
* 设备名称
*/
private String name;
}
}

View File

@ -0,0 +1,20 @@
package com.sunyard.chsm.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.CryptoServiceDTO;
/**
* @author liulu
* @since 2024/10/15
*/
public interface CryptoServiceService {
Page<CryptoServiceDTO.View> selectPageList(CryptoServiceDTO.Query query);
Long save(CryptoServiceDTO.Save save);
void update(CryptoServiceDTO.Save update);
void delete(Long id);
}

View File

@ -0,0 +1,19 @@
package com.sunyard.chsm.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.DeviceGroupDTO;
/**
* @author liulu
* @since 2024/10/17
*/
public interface DeviceGroupService {
Page<DeviceGroupDTO.View> selectPageList(DeviceGroupDTO.Query query);
Long save(DeviceGroupDTO.Save save);
void update(DeviceGroupDTO.Save update);
void delete(Long id);
}

View File

@ -0,0 +1,24 @@
package com.sunyard.chsm.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.DeviceDTO;
import java.util.List;
/**
* @author liulu
* @since 2024/10/17
*/
public interface DeviceService {
Page<DeviceDTO.View> selectPageList(DeviceDTO.Query query);
List<DeviceDTO.View> getUngroupedList();
DeviceDTO.Detail getDetailById(Long id);
Long save(DeviceDTO.Save save);
void update(DeviceDTO.Save update);
void delete(Long id);
}

View File

@ -0,0 +1,16 @@
package com.sunyard.chsm.service;
import com.sunyard.chsm.dto.KeyInfoDTO;
/**
* @author liulu
* @since 2024/10/23
*/
public interface KeyInfoService {
Long save(KeyInfoDTO.Save save);
}

View File

@ -0,0 +1,19 @@
package com.sunyard.chsm.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.KeyTemplateDTO;
/**
* @author liulu
* @since 2024/10/22
*/
public interface KeyTemplateService {
Page<KeyTemplateDTO.View> selectPageList(KeyTemplateDTO.Query query);
Long save(KeyTemplateDTO.Save save);
void update(KeyTemplateDTO.Save update);
void delete(Long id);
}

View File

@ -0,0 +1,193 @@
package com.sunyard.chsm.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.CryptoServiceDTO;
import com.sunyard.chsm.enums.ApiFunEnum;
import com.sunyard.chsm.enums.EnableStatus;
import com.sunyard.chsm.mapper.CryptoServiceApiMapper;
import com.sunyard.chsm.mapper.CryptoServiceMapper;
import com.sunyard.chsm.mapper.SpDeviceGroupMapper;
import com.sunyard.chsm.model.entity.CryptoService;
import com.sunyard.chsm.model.entity.CryptoServiceApi;
import com.sunyard.chsm.model.entity.DeviceGroup;
import com.sunyard.chsm.service.CryptoServiceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author liulu
* @since 2024/10/15
*/
@Slf4j
@Service
public class CryptoServiceServiceImpl implements CryptoServiceService {
@Resource
private CryptoServiceMapper cryptoServiceMapper;
@Resource
private CryptoServiceApiMapper cryptoServiceApiMapper;
@Resource
private SpDeviceGroupMapper spDeviceGroupMapper;
@Override
public Page<CryptoServiceDTO.View> selectPageList(CryptoServiceDTO.Query query) {
LambdaQueryWrapper<CryptoService> wrapper = new LambdaQueryWrapper<CryptoService>()
.like(StringUtils.hasText(query.getName()), CryptoService::getName, query.getName());
IPage<CryptoService> servicePage = cryptoServiceMapper.selectPage(
new Page<>(query.getPageNumber(), query.getPageSize()),
wrapper);
List<CryptoService> records = servicePage.getRecords();
if (CollectionUtils.isEmpty(records)) {
return new Page<>(servicePage.getCurrent(), servicePage.getSize(), servicePage.getTotal());
}
// service api
List<Long> ids = records.stream().map(CryptoService::getId).collect(Collectors.toList());
LambdaQueryWrapper<CryptoServiceApi> apiQuery = new LambdaQueryWrapper<CryptoServiceApi>()
.in(CryptoServiceApi::getCryptoServiceId, ids);
List<CryptoServiceApi> allServiceApis = cryptoServiceApiMapper.selectList(apiQuery);
Map<Long, List<CryptoServiceApi>> serviceApiMap = allServiceApis.stream()
.collect(Collectors.groupingBy(CryptoServiceApi::getCryptoServiceId));
List<CryptoServiceDTO.View> viewList = records.stream()
.map(it -> {
CryptoServiceDTO.View view = new CryptoServiceDTO.View();
BeanUtils.copyProperties(it, view);
Optional.ofNullable(EnableStatus.of(it.getStatus()))
.map(EnableStatus::getDesc)
.ifPresent(view::setStatusDesc);
List<CryptoServiceApi> serviceApis = serviceApiMap.getOrDefault(it.getId(), Collections.emptyList());
List<String> groupCodes = serviceApis.stream().map(CryptoServiceApi::getApiGroup)
.distinct().collect(Collectors.toList());
List<String> apiList = serviceApis.stream()
.map(CryptoServiceApi::getApiCode).collect(Collectors.toCollection(ArrayList::new));
apiList.addAll(groupCodes);
view.setApiList(apiList);
String apiDesc = serviceApis.stream()
.map(CryptoServiceApi::getApiName).collect(Collectors.joining(","));
view.setApiDesc(apiDesc);
return view;
})
.collect(Collectors.toList());
return new Page<CryptoServiceDTO.View>(servicePage.getCurrent(),
servicePage.getSize(), servicePage.getTotal()).setRecords(viewList);
}
@Transactional
@Override
public Long save(CryptoServiceDTO.Save save) {
checkName(save.getName());
CryptoService service = new CryptoService();
service.setName(save.getName());
DeviceGroup deviceGroup = spDeviceGroupMapper.selectById(save.getDeviceGroupId());
Assert.notNull(deviceGroup, "设备组不存在");
service.setDeviceGroupId(save.getDeviceGroupId());
service.setDeviceGroupName(deviceGroup.getName());
service.setStatus(EnableStatus.ENABLED.getCode());
service.setRemark(save.getRemark());
cryptoServiceMapper.insert(service);
// save apis
saveApis(save.getApiList(), service.getId());
return service.getId();
}
@Transactional
@Override
public void update(CryptoServiceDTO.Save update) {
CryptoService exist = cryptoServiceMapper.selectById(update.getId());
Assert.notNull(exist, "密码服务不存在");
if (!Objects.equals(update.getName(), exist.getName())) {
checkName(update.getName());
}
CryptoService up = new CryptoService();
up.setId(update.getId());
up.setName(update.getName());
if (!Objects.equals(update.getDeviceGroupId(), exist.getDeviceGroupId())) {
DeviceGroup deviceGroup = spDeviceGroupMapper.selectById(update.getDeviceGroupId());
Assert.notNull(deviceGroup, "设备组不存在");
up.setDeviceGroupId(update.getDeviceGroupId());
up.setDeviceGroupName(deviceGroup.getName());
}
up.setRemark(update.getRemark());
up.setUpdateTime(LocalDateTime.now());
cryptoServiceMapper.updateById(up);
LambdaQueryWrapper<CryptoServiceApi> wrapper = new LambdaQueryWrapper<CryptoServiceApi>()
.eq(CryptoServiceApi::getCryptoServiceId, exist.getId());
cryptoServiceApiMapper.delete(wrapper);
// save apis
saveApis(update.getApiList(), exist.getId());
}
@Transactional
@Override
public void delete(Long id) {
CryptoService exist = cryptoServiceMapper.selectById(id);
Assert.notNull(exist, "密码服务不存在");
Assert.isTrue(Objects.equals(EnableStatus.DISABLED.getCode(), exist.getStatus()),
"密码服务为启用状态, 无法删除");
LambdaQueryWrapper<CryptoServiceApi> wrapper = new LambdaQueryWrapper<CryptoServiceApi>()
.eq(CryptoServiceApi::getCryptoServiceId, id);
cryptoServiceApiMapper.delete(wrapper);
cryptoServiceMapper.deleteById(id);
}
private void checkName(String name) {
LambdaQueryWrapper<CryptoService> wrapper = new LambdaQueryWrapper<CryptoService>()
.eq(CryptoService::getName, name);
CryptoService exist = cryptoServiceMapper.selectOne(wrapper);
Assert.isNull(exist, "密码服务名称已存在");
}
private void saveApis(List<String> apiList, Long serviceId) {
Arrays.stream(ApiFunEnum.values())
.filter(it -> apiList.contains(it.getCode()))
.map(it -> {
CryptoServiceApi serviceApi = new CryptoServiceApi();
serviceApi.setCryptoServiceId(serviceId);
serviceApi.setApiGroup(it.getGroup().getCode());
serviceApi.setApiCode(it.getCode());
serviceApi.setApiName(it.getName());
return serviceApi;
})
.collect(Collectors.toList())
.forEach(cryptoServiceApiMapper::insert);
}
}

View File

@ -0,0 +1,167 @@
package com.sunyard.chsm.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.DeviceGroupDTO;
import com.sunyard.chsm.mapper.SpDeviceGroupMapper;
import com.sunyard.chsm.mapper.SpDeviceMapper;
import com.sunyard.chsm.model.entity.Device;
import com.sunyard.chsm.model.entity.DeviceGroup;
import com.sunyard.chsm.service.DeviceGroupService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author liulu
* @since 2024/10/21
*/
@Slf4j
@Service("sp_DeviceGroupServiceImpl")
public class DeviceGroupServiceImpl implements DeviceGroupService {
@Resource
private SpDeviceMapper spDeviceMapper;
@Resource
private SpDeviceGroupMapper spDeviceGroupMapper;
@Override
public Page<DeviceGroupDTO.View> selectPageList(DeviceGroupDTO.Query query) {
LambdaQueryWrapper<DeviceGroup> wrapper = new LambdaQueryWrapper<DeviceGroup>()
.like(StringUtils.hasText(query.getName()), DeviceGroup::getName, query.getName());
IPage<DeviceGroup> page = spDeviceGroupMapper.selectPage(
new Page<>(query.getPageNumber(), query.getPageSize()),
wrapper);
List<DeviceGroup> records = page.getRecords();
if (CollectionUtils.isEmpty(records)) {
return new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
}
List<Long> ids = records.stream().map(DeviceGroup::getId).collect(Collectors.toList());
Map<Long, List<Device>> groupMap = spDeviceMapper.selectList(
new LambdaQueryWrapper<Device>()
.in(Device::getGroupId, ids)
).stream().collect(Collectors.groupingBy(Device::getGroupId));
List<DeviceGroupDTO.View> viewList = records.stream()
.map(it -> {
DeviceGroupDTO.View view = new DeviceGroupDTO.View();
BeanUtils.copyProperties(it, view);
Map<String, String> deviceNames = groupMap.getOrDefault(it.getId(), Collections.emptyList())
.stream()
.collect(Collectors.toMap(it2 -> String.valueOf(it2.getId()), Device::getName));
view.setDeviceNames(String.join(",", deviceNames.values()));
return view;
})
.collect(Collectors.toList());
return new Page<DeviceGroupDTO.View>(page.getCurrent(), page.getSize(), page.getTotal()).setRecords(viewList);
}
@Transactional
@Override
public Long save(DeviceGroupDTO.Save save) {
checkName(save.getName());
DeviceGroup add = new DeviceGroup();
add.setName(save.getName());
add.setRemark(save.getRemark());
add.setCreateTime(LocalDateTime.now());
spDeviceGroupMapper.insert(add);
// 设备和组关系绑定
if (!CollectionUtils.isEmpty(save.getDeviceIds())) {
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<Device>()
.in(Device::getId, save.getDeviceIds());
Device up = new Device();
up.setGroupId(add.getId());
up.setGroupName(save.getName());
spDeviceMapper.update(up, wrapper);
}
return add.getId();
}
@Transactional
@Override
public void update(DeviceGroupDTO.Save update) {
Assert.notNull(update.getId(), "id不能为空");
DeviceGroup exist = spDeviceGroupMapper.selectById(update.getId());
Assert.notNull(exist, "id对应的设备组不存在");
if (!Objects.equals(exist.getName(), update.getName())) {
checkName(update.getName());
}
DeviceGroup upGroup = new DeviceGroup();
upGroup.setId(update.getId());
upGroup.setName(update.getName());
upGroup.setRemark(update.getRemark());
upGroup.setUpdateTime(LocalDateTime.now());
spDeviceGroupMapper.updateById(upGroup);
Device reset = new Device();
reset.setGroupId(0L);
reset.setGroupName("");
LambdaQueryWrapper<Device> resetWrapper = new LambdaQueryWrapper<Device>()
.eq(Device::getGroupId, update.getId());
spDeviceMapper.update(reset, resetWrapper);
// 设备和组关系绑定
if (!CollectionUtils.isEmpty(update.getDeviceIds())) {
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<Device>()
.in(Device::getId, update.getDeviceIds());
Device up = new Device();
up.setGroupId(update.getId());
up.setGroupName(update.getName());
spDeviceMapper.update(up, wrapper);
}
}
private void checkName(String name) {
LambdaQueryWrapper<DeviceGroup> wrapper = new LambdaQueryWrapper<DeviceGroup>()
.eq(DeviceGroup::getName, name);
DeviceGroup exist = spDeviceGroupMapper.selectOne(wrapper);
Assert.isNull(exist, "设备组名称已存在");
}
@Transactional
@Override
public void delete(Long id) {
Assert.notNull(id, "id不能为空");
DeviceGroup exist = spDeviceGroupMapper.selectById(id);
Assert.notNull(exist, "id对应的设备组不存在");
LambdaQueryWrapper<Device> resetWrapper = new LambdaQueryWrapper<Device>()
.eq(Device::getGroupId, id);
Long count = spDeviceMapper.selectCount(resetWrapper);
Assert.isTrue(count <= 0, "设备组存在设备, 不能删除");
spDeviceGroupMapper.deleteById(id);
}
}

View File

@ -0,0 +1,168 @@
package com.sunyard.chsm.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.DeviceDTO;
import com.sunyard.chsm.enums.ManufacturerEnum;
import com.sunyard.chsm.enums.ManufacturerModelEnum;
import com.sunyard.chsm.mapper.SpDeviceMapper;
import com.sunyard.chsm.model.entity.Device;
import com.sunyard.chsm.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author liulu
* @since 2024/10/17
*/
@Slf4j
@Service("sp_DeviceServiceImpl")
public class DeviceServiceImpl implements DeviceService {
@Resource
private SpDeviceMapper spDeviceMapper;
@Override
public Page<DeviceDTO.View> selectPageList(DeviceDTO.Query query) {
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<Device>()
.eq(StringUtils.hasText(query.getManufacturers()), Device::getManufacturer, query.getManufacturers())
.eq(StringUtils.hasText(query.getModel()), Device::getManufacturerModel, query.getModel())
.like(StringUtils.hasText(query.getName()), Device::getName, query.getName());
IPage<Device> page = spDeviceMapper.selectPage(
new Page<>(query.getPageNumber(), query.getPageSize()),
wrapper);
List<Device> records = page.getRecords();
if (CollectionUtils.isEmpty(records)) {
return new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
}
List<DeviceDTO.View> viewList = records.stream()
.map(it -> {
DeviceDTO.View view = new DeviceDTO.View();
BeanUtils.copyProperties(it, view);
Optional.ofNullable(ManufacturerEnum.of(it.getManufacturer()))
.map(ManufacturerEnum::getName)
.ifPresent(view::setManufacturerText);
Optional.ofNullable(ManufacturerModelEnum.of(it.getManufacturerModel()))
.map(ManufacturerModelEnum::getName)
.ifPresent(view::setManufacturerModelText);
return view;
})
.collect(Collectors.toList());
return new Page<DeviceDTO.View>(page.getCurrent(), page.getSize(), page.getTotal()).setRecords(viewList);
}
@Override
public List<DeviceDTO.View> getUngroupedList() {
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<Device>()
.eq(Device::getGroupId, 0L);
List<Device> devices = spDeviceMapper.selectList(wrapper);
return devices.stream()
.map(it -> {
DeviceDTO.View view = new DeviceDTO.View();
BeanUtils.copyProperties(it, view);
Optional.ofNullable(ManufacturerEnum.of(it.getManufacturer()))
.map(ManufacturerEnum::getName)
.ifPresent(view::setManufacturerText);
Optional.ofNullable(ManufacturerModelEnum.of(it.getManufacturerModel()))
.map(ManufacturerModelEnum::getName)
.ifPresent(view::setManufacturerModelText);
return view;
})
.collect(Collectors.toList());
}
@Override
public DeviceDTO.Detail getDetailById(Long id) {
Device exist = spDeviceMapper.selectById(id);
Assert.notNull(exist, "查询的数据不存在");
DeviceDTO.Detail detail = new DeviceDTO.Detail();
BeanUtils.copyProperties(exist, detail);
Optional.ofNullable(ManufacturerEnum.of(exist.getManufacturer()))
.map(ManufacturerEnum::getName)
.ifPresent(detail::setManufacturerText);
Optional.ofNullable(ManufacturerModelEnum.of(exist.getManufacturerModel()))
.map(ManufacturerModelEnum::getName)
.ifPresent(detail::setManufacturerModelText);
// todo
detail.setCpuRate(0.5D);
detail.setMemoryRate(0.5D);
detail.setDiskRate(0.5D);
return detail;
}
@Transactional
@Override
public Long save(DeviceDTO.Save save) {
ManufacturerEnum manufacturer = ManufacturerEnum.of(save.getManufacturer());
Assert.notNull(manufacturer, "不支持的设备厂商: " + save.getManufacturer());
ManufacturerModelEnum manufacturerModel = ManufacturerModelEnum.of(save.getManufacturerModel());
Assert.notNull(manufacturerModel, "不支持的设备型号: " + save.getManufacturerModel());
Assert.isTrue(manufacturerModel.getManufacturer() == manufacturer, "设备厂商和型号不匹配");
checkName(save.getName());
Device device = new Device();
BeanUtils.copyProperties(save, device);
device.setId(null);
device.setGroupId(0L);
device.setGroupName("");
device.setWeight(1);
device.setCreateTime(LocalDateTime.now());
spDeviceMapper.insert(device);
return device.getId();
}
@Transactional
@Override
public void update(DeviceDTO.Save update) {
Assert.notNull(update.getId(), "id不能为空");
Device exist = spDeviceMapper.selectById(update.getId());
Assert.notNull(exist, "id对应的设备不存在");
if (!Objects.equals(exist.getName(), update.getName())) {
checkName(update.getName());
}
Device up = new Device();
BeanUtils.copyProperties(update, up);
up.setUpdateTime(LocalDateTime.now());
spDeviceMapper.updateById(up);
}
@Transactional
@Override
public void delete(Long id) {
spDeviceMapper.deleteById(id);
}
private void checkName(String name) {
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<Device>()
.eq(Device::getName, name);
Device exist = spDeviceMapper.selectOne(wrapper);
Assert.isNull(exist, "设备名称已存在");
}
}

View File

@ -0,0 +1,113 @@
package com.sunyard.chsm.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.sunyard.chsm.dto.KeyInfoDTO;
import com.sunyard.chsm.enums.KeyCategory;
import com.sunyard.chsm.enums.KeyStatus;
import com.sunyard.chsm.mapper.KeyInfoMapper;
import com.sunyard.chsm.mapper.KeyTemplateMapper;
import com.sunyard.chsm.mapper.SpKeyRecordMapper;
import com.sunyard.chsm.model.entity.KeyInfo;
import com.sunyard.chsm.model.entity.KeyRecord;
import com.sunyard.chsm.model.entity.KeyTemplate;
import com.sunyard.chsm.sdf.SdfApiService;
import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.service.KeyInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
/**
* @author liulu
* @since 2024/10/23
*/
@Slf4j
@Service
public class KeyInfoServiceImpl implements KeyInfoService {
@Resource
private KeyInfoMapper keyInfoMapper;
@Resource
private SpKeyRecordMapper spKeyRecordMapper;
@Resource
private KeyTemplateMapper keyTemplateMapper;
@Resource
private SdfApiService sdfApiService;
@Transactional
@Override
public Long save(KeyInfoDTO.Save save) {
KeyTemplate keyTemplate = keyTemplateMapper.selectOne(
new LambdaQueryWrapper<KeyTemplate>()
.eq(KeyTemplate::getCode, save.getKeyTemplateCode())
);
Assert.notNull(keyTemplate, "密钥模版不存在");
LocalDateTime now = LocalDateTime.now();
for (int i = 0; i < save.getGenNumber(); i++) {
// 密钥信息
KeyInfo info = new KeyInfo();
info.setId(IdWorker.getId());
info.setApplicationId(save.getApplicationId());
info.setKeyTemplateId(keyTemplate.getId());
info.setCode(String.valueOf(info.getId()));
info.setKeyType(keyTemplate.getKeyType());
info.setKeyAlg(keyTemplate.getKeyAlg());
info.setKeyLength(keyTemplate.getKeyLength());
info.setKeyUsage(keyTemplate.getKeyUsage());
info.setCheckAlg(keyTemplate.getCheckAlg());
info.setCreateTime(LocalDateTime.now());
info.setStatus(KeyStatus.ENABLED.getCode());
ChronoUnit startUnit = ChronoUnit.valueOf(keyTemplate.getStartAfterCreateUnit().toUpperCase());
info.setEffectiveTime(now.plusSeconds(startUnit.getDuration().getSeconds() * keyTemplate.getStartAfterCreateTime()));
ChronoUnit validUnit = ChronoUnit.valueOf(keyTemplate.getValidUnit().toUpperCase());
info.setExpiredTime(info.getEffectiveTime().plusSeconds(validUnit.getDuration().getSeconds() * keyTemplate.getValidTime()));
// 具体使用的密钥值
KeyRecord record = new KeyRecord();
record.setId(IdWorker.getId());
record.setKeyId(info.getId());
record.setKeyIndex(String.valueOf(record.getId()));
record.setCheckAlg(keyTemplate.getCheckAlg());
record.setEffectiveTime(info.getEffectiveTime());
record.setExpiredTime(info.getExpiredTime());
record.setCreateTime(LocalDateTime.now());
if (KeyCategory.SYM_KEY.getCode().equals(keyTemplate.getKeyType())) {
byte[] symKey = sdfApiService.generateRandom(16);
record.setKeyData(Hex.encodeHexString(symKey));
String checkHash = Hex.encodeHexString(sdfApiService.hash(symKey));
record.setCheckValue(checkHash);
info.setCheckValue(checkHash);
} else {
EccKey eccKey = sdfApiService.genKeyPairEcc();
byte[] d = eccKey.getPriKey().getD();
record.setKeyData(Hex.encodeHexString(d));
String checkHash = Hex.encodeHexString(sdfApiService.hash(d));
record.setCheckValue(checkHash);
info.setCheckValue(checkHash);
byte[] pubKeyBytes = eccKey.getPubKey().getPubKeyBytes();
record.setPubKey(Hex.encodeHexString(pubKeyBytes));
}
keyInfoMapper.insert(info);
spKeyRecordMapper.insert(record);
}
return 0L;
}
}

View File

@ -0,0 +1,166 @@
package com.sunyard.chsm.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.chsm.dto.KeyTemplateDTO;
import com.sunyard.chsm.enums.KeyAlg;
import com.sunyard.chsm.enums.KeyCategory;
import com.sunyard.chsm.enums.KeyUsage;
import com.sunyard.chsm.mapper.KeyTemplateMapper;
import com.sunyard.chsm.model.entity.KeyTemplate;
import com.sunyard.chsm.service.KeyTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author liulu
* @since 2024/10/22
*/
@Slf4j
@Service
public class KeyTemplateServiceImpl implements KeyTemplateService {
@Resource
private KeyTemplateMapper keyTemplateMapper;
@Override
public Page<KeyTemplateDTO.View> selectPageList(KeyTemplateDTO.Query query) {
LambdaQueryWrapper<KeyTemplate> wrapper = new LambdaQueryWrapper<KeyTemplate>()
.like(StringUtils.hasText(query.getKeyType()), KeyTemplate::getKeyType, query.getKeyType());
IPage<KeyTemplate> page = keyTemplateMapper.selectPage(
new Page<>(query.getPageNumber(), query.getPageSize()),
wrapper);
List<KeyTemplate> records = page.getRecords();
if (CollectionUtils.isEmpty(records)) {
return new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
}
List<KeyTemplateDTO.View> viewList = records.stream()
.map(it -> {
KeyTemplateDTO.View view = new KeyTemplateDTO.View();
BeanUtils.copyProperties(it, view);
Optional.ofNullable(KeyCategory.of(it.getKeyType()))
.map(KeyCategory::getDesc)
.ifPresent(view::setKeyTypeText);
Map<String, String> usageMap = KeyUsage.getUsage(it.getKeyUsage())
.stream()
.collect(Collectors.toMap(KeyUsage::getCode, KeyUsage::getDesc));
view.setKeyUsages(new ArrayList<>(usageMap.keySet()));
view.setKeyUsageText(String.join(",", usageMap.values()));
return view;
})
.collect(Collectors.toList());
return new Page<KeyTemplateDTO.View>(page.getCurrent(), page.getSize(), page.getTotal()).setRecords(viewList);
}
@Override
public Long save(KeyTemplateDTO.Save save) {
checkEnum(save);
checkCode(save.getCode());
KeyTemplate add = mapToEntity(save);
add.setCreateTime(LocalDateTime.now());
keyTemplateMapper.insert(add);
return add.getId();
}
@Override
public void update(KeyTemplateDTO.Save update) {
Assert.notNull(update.getId(), "id不能为空");
checkEnum(update);
KeyTemplate exist = keyTemplateMapper.selectById(update.getId());
Assert.notNull(exist, "要更新的密钥模版不存在");
if (!Objects.equals(exist.getCode(), update.getCode())) {
checkCode(update.getCode());
}
KeyTemplate up = mapToEntity(update);
up.setId(update.getId());
up.setUpdateTime(LocalDateTime.now());
keyTemplateMapper.updateById(up);
}
@Override
public void delete(Long id) {
Assert.notNull(id, "id不能为空");
KeyTemplate exist = keyTemplateMapper.selectById(id);
Assert.notNull(exist, "要更新的密钥模版不存在");
keyTemplateMapper.deleteById(id);
}
private KeyTemplate mapToEntity(KeyTemplateDTO.Save save) {
KeyTemplate entity = new KeyTemplate();
entity.setCode(save.getCode());
entity.setName(save.getName());
entity.setKeyType(save.getKeyType());
entity.setKeyAlg(save.getKeyAlg());
entity.setKeyLength(save.getKeyLength());
entity.setKeyUsage(KeyUsage.getStatus(save.getKeyUsages()));
entity.setCheckAlg("SM3");
entity.setValidTime(save.getValidTime());
entity.setValidUnit(save.getValidUnit());
entity.setStartAfterCreateTime(save.getStartAfterCreateTime());
entity.setStartAfterCreateUnit(save.getStartAfterCreateUnit());
entity.setRemark(save.getRemark());
return entity;
}
private void checkEnum(KeyTemplateDTO.Save save) {
KeyCategory keyCategory = KeyCategory.of(save.getKeyType());
Assert.notNull(keyCategory, "不支持的密钥类型: " + save.getKeyType());
KeyAlg keyAlg = KeyAlg.of(save.getKeyAlg());
Assert.notNull(keyAlg, "不支持的密钥算法: " + save.getKeyAlg());
Assert.isTrue(keyAlg.getCategory() == keyCategory, "密钥类型和密钥算法不匹配");
List<KeyUsage> usageList = save.getKeyUsages().stream()
.map(String::toUpperCase)
.map(KeyUsage::valueOf)
.collect(Collectors.toList());
if (KeyCategory.SYM_KEY == keyCategory ) {
Assert.isTrue(!usageList.contains(KeyUsage.SIGN_VERIFY), "对称密钥不能用于签名验签");
} else {
Assert.isTrue(!usageList.contains(KeyUsage.HMAC), "非对称密钥不能用于计算HMac");
Assert.isTrue(!usageList.contains(KeyUsage.MAC), "非对称密钥不能用于计算MAC");
}
ChronoUnit validUnit = ChronoUnit.valueOf(save.getValidUnit().toUpperCase());
Assert.isTrue(validUnit == ChronoUnit.YEARS || validUnit == ChronoUnit.MONTHS
|| validUnit == ChronoUnit.DAYS, "密钥有效期时间单位仅支持年月日");
ChronoUnit startUnit = ChronoUnit.valueOf(save.getStartAfterCreateUnit().toUpperCase());
Assert.isTrue(startUnit == ChronoUnit.MONTHS || startUnit == ChronoUnit.DAYS
|| startUnit == ChronoUnit.HOURS, "延迟生效时间单位仅支持月日小时");
}
private void checkCode(String code) {
LambdaQueryWrapper<KeyTemplate> wrapper = new LambdaQueryWrapper<KeyTemplate>()
.eq(KeyTemplate::getCode, code);
KeyTemplate exist = keyTemplateMapper.selectOne(wrapper);
Assert.isNull(exist, "模版编号已存在");
}
}

View File

@ -0,0 +1,30 @@
package com.sunyard.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author liulu
* @since 2024/10/28
*/
@Configuration
@MapperScan({"com.sunyard.ssp.**.mapper","com.sunyard.chsm.**.mapper"})
public class MyBatisConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 如果配置多个插件, 切记分页最后添加
// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.DM));
return interceptor;
}
}

View File

@ -1,8 +1,5 @@
package com.sunyard.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@ -12,12 +9,13 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.sunyard.utils.DateFormatPattern;
import org.mybatis.spring.annotation.MapperScan;
import com.sunyard.chsm.utils.DateFormatPattern;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
@ -28,21 +26,29 @@ import java.time.format.DateTimeFormatter;
* @since 2024/10/25
*/
@Configuration
@MapperScan("com.sunyard.ssp.**.mapper")
public class WebConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 如果配置多个插件, 切记分页最后添加
// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.DM));
return interceptor;
}
public CommonsRequestLoggingFilter requestLoggingFilter() {
CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter(){
@Override
protected boolean shouldLog(HttpServletRequest request) {
return true;
}
@Override
protected void beforeRequest(HttpServletRequest request, String message) {
logger.info(message);
}
};
loggingFilter.setIncludeHeaders(false);
loggingFilter.setIncludeClientInfo(true);
loggingFilter.setIncludeQueryString(true);
loggingFilter.setIncludePayload(true);
loggingFilter.setMaxPayloadLength(2000);
return loggingFilter;
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer objectMapperBuilderCustomizer() {

View File

@ -79,16 +79,16 @@ public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticatio
}
}
String username = ((UserDetails)authentication.getPrincipal()).getUsername();
System.out.println("loginSuccess username:" + username + "begin:" + (beginTime - System.currentTimeMillis()));
log.info("loginSuccess username:" + username + "begin:" + (beginTime - System.currentTimeMillis()));
List<GrantedAuthority> authorities = (List<GrantedAuthority>) ((UserDetails)authentication.getPrincipal()).getAuthorities();
List<String> list = new ArrayList<>();
for(GrantedAuthority g : authorities){
list.add(g.getAuthority());
}
System.out.println("loginSuccess username:" + username + "getCurrUser begin:" + (beginTime - System.currentTimeMillis()));
log.info("loginSuccess username:" + username + "getCurrUser begin:" + (beginTime - System.currentTimeMillis()));
ScUser scuser = securityUtil.getCurrUser();
//ipInfoUtil.getUrl(request);
System.out.println("loginSuccess username:" + username + "getCurrUser end:" + (beginTime - System.currentTimeMillis()));
log.info("loginSuccess username:" + username + "getCurrUser end:" + (beginTime - System.currentTimeMillis()));
// 登陆成功生成token
String token;
if(tokenRedis){
@ -138,7 +138,7 @@ public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticatio
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("access-control-allow-headers", "Content-Type,Accept,Authorization,accesstoken");
/*sunyard end*/
System.out.println("loginSuccess username:" + username + "end:" + (beginTime - System.currentTimeMillis()));
log.info("loginSuccess username:" + username + "end:" + (beginTime - System.currentTimeMillis()));
ResponseUtil.out(response, ResponseUtil.resultMap(true,200,msg, token));
}
}

View File

@ -59,9 +59,6 @@ public class JWTAuthenticationFilter extends BasicAuthenticationFilter {
/*sunyard*/
String method = request.getMethod();
System.out.println( method );
System.out.println( request.getRequestURI() );
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, HEAD, DELETE");
response.setHeader("Access-Control-Allow-Origin", "*");

View File

@ -1,14 +1,22 @@
package com.sunyard.ssp.common.exception;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.utils.ThrowableUtils;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.Arrays;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.Optional;
/**
* 全局controller异常处理
@ -19,7 +27,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @date: 2020/5/25 16:24
*/
@Slf4j
@ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionResolver {
/**
@ -41,7 +49,7 @@ public class GlobalExceptionResolver {
@ExceptionHandler(MyBatisSystemException.class)
@ResponseBody
public Result<Object> handleMyBatisSystemException(MyBatisSystemException e) {
System.out.println("数据持久层");
log.info("数据持久层");
return new ResultUtil().setErrorMsg(e.getLocalizedMessage());
}
@ -51,46 +59,45 @@ public class GlobalExceptionResolver {
@ExceptionHandler(BindException.class)
@ResponseBody
public Result<Object> handleBindException(BindException e) {
System.out.println("校验器");
log.info("校验器");
FieldError fieldError = e.getBindingResult().getFieldError();
return new ResultUtil().setErrorMsg(fieldError.getDefaultMessage());
}
// @ExceptionHandler(MethodArgumentNotValidException.class)
// public R<?> validExceptionHandler(MethodArgumentNotValidException ex) {
//
// return Optional.of(ex.getBindingResult())
// .map(BindingResult::getFieldError)
// .map(FieldError::getDefaultMessage)
// .map(message -> R.error(400, message))
// .get();
// }
//
// private static final List<Class<? extends Exception>> EX_CLASS = Arrays.asList(
// IllegalArgumentException.class, IllegalStateException.class,
// IllegalFormatException.class,
// SspwebException.class,
// UnsupportedOperationException.class);
//
// @ExceptionHandler(Exception.class)
// public R<?> exceptionHandler(Exception ex) {
// String errorMessage = ThrowableUtils.buildErrorMessage(ex);
// SspwebException serviceException = ThrowableUtils.findException(SspwebException.class, ex);
// if (serviceException != null) {
// log.warn("Validation failed -> {}, errorMessage: \n {}", serviceException.getMessage(), errorMessage);
// return R.error(400, serviceException.getMessage());
// }
//
// for (Class<? extends Exception> eClass : EX_CLASS) {
// Exception exception = ThrowableUtils.findException(eClass, ex);
// if (exception == null) {
// continue;
// }
// log.warn("Validation failed -> {} ", errorMessage);
// return R.error(400, exception.getMessage());
// }
// log.error("系统异常 -> ", ex);
// return R.error("系统异常");
// }
@ExceptionHandler(MethodArgumentNotValidException.class)
public R<?> validExceptionHandler(MethodArgumentNotValidException ex) {
return Optional.of(ex)
.map(MethodArgumentNotValidException::getFieldError)
.map(FieldError::getDefaultMessage)
.map(message -> R.error(400, message))
.get();
}
private static final List<Class<? extends Exception>> EX_CLASS = Arrays.asList(
IllegalArgumentException.class, IllegalStateException.class,
IllegalFormatException.class,
SspwebException.class,
UnsupportedOperationException.class);
@ExceptionHandler(Exception.class)
public R<?> exceptionHandler(Exception ex) {
String errorMessage = ThrowableUtils.buildErrorMessage(ex);
SspwebException serviceException = ThrowableUtils.findException(SspwebException.class, ex);
if (serviceException != null) {
log.warn("Validation failed -> {}, errorMessage: \n {}", serviceException.getMessage(), errorMessage);
return R.error(400, serviceException.getMessage());
}
for (Class<? extends Exception> eClass : EX_CLASS) {
Exception exception = ThrowableUtils.findException(eClass, ex);
if (exception == null) {
continue;
}
log.warn("Validation failed -> {} ", errorMessage);
return R.error(400, exception.getMessage());
}
log.error("系统异常 -> ", ex);
return R.error("系统异常");
}
}

View File

@ -70,7 +70,6 @@ public class ParamConfServiceImpl extends ServiceImpl<ParamConfMapper, ParamConf
paramConf = new ParamConf();
paramConf.setItem(item);
paramConf.setStatus(0);
System.out.println(LocalDateTime.now());
paramConf.setCreatTime(LocalDateTime.now());
paramConf.setKey(key);
paramConf.setValue(String.valueOf(map.get(key)));
@ -157,7 +156,7 @@ public class ParamConfServiceImpl extends ServiceImpl<ParamConfMapper, ParamConf
*/
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("初始化系统参数-----------------");
// System.out.println("初始化系统参数-----------------");
// List<ParamConf> paramConfs = getParamConfByJsonFile();
// paramConfs.forEach(paramConf -> {
// ParamConf temp = selectByKey(paramConf.getKey());

View File

@ -31,7 +31,7 @@ public class RedisConfig {
MessageListenerAdapter messageListener() {
//abstract methods overwrite
return new MessageListenerAdapter((MessageListener) (message, pattern) -> {
System.out.println("Message received: " + message.toString());
log.info("Message received: " + message.toString());
});
}

View File

@ -6,6 +6,7 @@ import com.google.protobuf.UInt64Value;
import com.sunyard.ssp.proto.control.Control;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import redis.clients.jedis.BinaryJedisPubSub;
@ -18,6 +19,7 @@ import java.util.List;
* @date:2020/3/19
* @description:
*/
@Slf4j
public class ServerTest {
/**
@ -105,7 +107,6 @@ public class ServerTest {
System.err.println("接收命令响应超时!");
} else {
val list = res.getData().unpack( Control.VOChannelList.class );
System.out.println(list);
}
} catch (Exception e) {
@ -138,7 +139,6 @@ public class ServerTest {
System.err.println("接收命令响应超时!");
} else {
val list = res.getData().unpack( Control.VOChannelList.class );
System.out.println(list);
}
} catch (Exception e) {
e.printStackTrace();

View File

@ -1,5 +1,6 @@
package com.sunyard.ssp.utils;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
@ -54,6 +55,7 @@ import java.util.Set;
* @date:2020/4/27
* @description:
*/
@Slf4j
public class CaUtil {
static {
@ -61,7 +63,7 @@ public class CaUtil {
BouncyCastleProvider bc = new BouncyCastleProvider();
Set<Provider.Service> services = bc.getServices();
for (Provider.Service s:services){
if (s.toString().toUpperCase().contains("CIPHER")) System.out.println(s.toString());
if (s.toString().toUpperCase().contains("CIPHER")) log.info(s.toString());
}
}
@ -75,7 +77,7 @@ public class CaUtil {
}
public static void genGMCACert() throws Exception {
System.out.println("=============测试生成国密CA根证书=============");
log.info("=============测试生成国密CA根证书=============");
KeyPairGenerator g = KeyPairGenerator.getInstance("EC", "BC");
g.initialize(new ECNamedCurveGenParameterSpec("sm2p256v1"));
@ -85,7 +87,7 @@ public class CaUtil {
PrivateKey privKey = p.getPrivate();
PublicKey pubKey = p.getPublic();
System.out.println("CA PrivateKey:" + Base64.toBase64String(privKey.getEncoded()));
log.info("CA PrivateKey:" + Base64.toBase64String(privKey.getEncoded()));
X500Principal iss = new X500Principal("CN=test GM ROOT CA,OU=test,C=CN,S=Guangdong,O=test");
@ -121,16 +123,16 @@ public class CaUtil {
cert = (X509Certificate) fact.generateCertificate(bIn);
System.out.println("CA Cert:" + Base64.toBase64String(cert.getEncoded()));
log.info("CA Cert:" + Base64.toBase64String(cert.getEncoded()));
saveFile("CAPrikey", privKey.getEncoded());
saveFile("CARootCert.cer", cert.getEncoded());
System.out.println("=============测试生成国密CA根证书=============");
log.info("=============测试生成国密CA根证书=============");
}
public static void genCertWithCaSign() throws Exception {
System.out.println("=============测试国密CA根证书签发国密证书=============");
log.info("=============测试国密CA根证书签发国密证书=============");
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(readFile("CAPrikey"));
@ -182,16 +184,16 @@ public class CaUtil {
cert = (X509Certificate) fact.generateCertificate(bIn);
System.out.println("custCert:" + Base64.toBase64String(cert.getEncoded()));
System.out.println("custPrivateKey:" + Base64.toBase64String(privKey.getEncoded()));
log.info("custCert:" + Base64.toBase64String(cert.getEncoded()));
log.info("custPrivateKey:" + Base64.toBase64String(privKey.getEncoded()));
saveFile("custCert.cer", cert.getEncoded());
saveFile("custPrivateKey", privKey.getEncoded());
System.out.println("=============测试国密CA根证书签发国密证书=============");
log.info("=============测试国密CA根证书签发国密证书=============");
}
public static void testDigitalSign() throws Exception {
System.out.println("=============测试国密证书数字签名=============");
log.info("=============测试国密证书数字签名=============");
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(readFile("custPrivateKey"));
KeyFactory keyFactory = KeyFactory.getInstance("EC");
@ -211,9 +213,9 @@ public class CaUtil {
byte[] digitalsignature = signature.sign();
System.out.println("signText:" + signText);
log.info("signText:" + signText);
System.out.println("digitalsignature:" + Base64.toBase64String(digitalsignature));
log.info("digitalsignature:" + Base64.toBase64String(digitalsignature));
Signature signature1 = Signature.getInstance("SM3withSM2", "BC");
@ -223,7 +225,7 @@ public class CaUtil {
boolean result = signature1.verify(digitalsignature);
System.out.println("verifyResult:" + result);
log.info("verifyResult:" + result);
Signature signature2 = Signature.getInstance("SM3withSM2", "BC");
@ -233,15 +235,15 @@ public class CaUtil {
boolean exceptionResult = signature2.verify(digitalsignature);
System.out.println("exceptionVerifyResult:" + exceptionResult);
log.info("exceptionVerifyResult:" + exceptionResult);
System.out.println("=============测试国密证书数字签名=============");
log.info("=============测试国密证书数字签名=============");
}
public static void testSM2EcDc() throws Exception {
System.out.println("=============测试国密SM2加解密=============");
log.info("=============测试国密SM2加解密=============");
//从证书获取公钥
CertificateFactory certificateFactory = CertificateFactory.getInstance("X509", "BC");
@ -258,14 +260,14 @@ public class CaUtil {
//待加密数据
byte[] ebs = "123sssss测试".getBytes("UTF-8");
System.out.println("原文:"+new String(ebs));
log.info("原文:"+new String(ebs));
//初始化加密引擎
SM2Engine sm2EncEngine = new SM2Engine();
sm2EncEngine.init(true, new ParametersWithRandom(localECPublicKeyParameters));
//加密
byte[] bs = sm2EncEngine.processBlock(ebs,0,ebs.length);
String es = Base64.toBase64String(bs);
System.out.println("密文:"+es);
log.info("密文:"+es);
//获取私钥
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(readFile("custPrivateKey"));
@ -285,13 +287,13 @@ public class CaUtil {
sm2DcEngine.init(false, localECPrivateKeyParameters);
bs = Base64.decode(es.getBytes("Utf-8"));
byte[] b = sm2DcEngine.processBlock(bs,0,bs.length);
System.out.println("明文:"+new String(b));
log.info("明文:"+new String(b));
System.out.println("=============测试国密SM2加解密=============");
log.info("=============测试国密SM2加解密=============");
}
public static void testSaveGMKeyStore() throws Exception {
System.out.println("=============测试国密证书PKCS12 KeyStore存取=============");
log.info("=============测试国密证书PKCS12 KeyStore存取=============");
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(readFile("custPrivateKey"));
KeyFactory keyFactory = KeyFactory.getInstance("EC");
@ -318,11 +320,11 @@ public class CaUtil {
PrivateKey privateKey1 = (PrivateKey) keyStore1.getKey("test", "32145698745632145698745632145698".toCharArray());
System.out.println("公钥证书存取前后对比:" + Arrays.equals(certificate1.getEncoded(), certificate.getEncoded()));
log.info("公钥证书存取前后对比:" + Arrays.equals(certificate1.getEncoded(), certificate.getEncoded()));
System.out.println("私钥存取前后对比:" + Arrays.equals(privateKey.getEncoded(), privateKey1.getEncoded()));
log.info("私钥存取前后对比:" + Arrays.equals(privateKey.getEncoded(), privateKey1.getEncoded()));
System.out.println("=============测试国密证书PKCS12 KeyStore存取=============");
log.info("=============测试国密证书PKCS12 KeyStore存取=============");
}

View File

@ -87,7 +87,7 @@ public class SM2Util extends GMBaseUtil {
}
// 3059301306072A8648CE3D020106082A811CCF5501822D03420004EB1F1EC734D710C016B171C4A0DC5418BD9AE89EEFE8DA7C36D7192B40F8CF9B80EFF7D62F98A9D84BF910B85AD8F2F19D8DC1EE61458A01B7FB21C1850C7290
// System.out.println(pk);
// log.info(pk);
// EB1F1EC734D710C016B171C4A0DC5418BD9AE89EEFE8DA7C36D7192B40F8CF9B80EFF7D62F98A9D84BF910B85AD8F2F19D8DC1EE61458A01B7FB21C1850C7290
@ -97,8 +97,8 @@ public class SM2Util extends GMBaseUtil {
String xHex = pkDer.substring(0, 64);
String yHex = pkDer.substring(64);
// System.out.println("x=" + xHex);
// System.out.println("y=" + yHex);
// log.info("x=" + xHex);
// log.info("y=" + yHex);
ECPublicKeyParameters pubKey = BCECUtil.createECPublicKeyParameters(xHex, yHex, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS);
@ -459,7 +459,7 @@ public class SM2Util extends GMBaseUtil {
}
signer.init(true, param);
System.out.println("Z=" + BytesUtil.bytes2HexString((byte[]) ReflectUtil.getFieldValue( signer, "z")));
log.info("Z=" + BytesUtil.bytes2HexString((byte[]) ReflectUtil.getFieldValue( signer, "z")));
signer.update(srcData, 0, srcData.length);
return signer.generateSignature();
@ -559,13 +559,13 @@ public class SM2Util extends GMBaseUtil {
param = pubKeyParameters;
}
signer.init(false, param);
System.out.println("Z=" + BytesUtil.bytes2HexString((byte[]) ReflectUtil.getFieldValue( signer, "z")));
log.info("Z=" + BytesUtil.bytes2HexString((byte[]) ReflectUtil.getFieldValue( signer, "z")));
// Digest digest = (Digest) ReflectUtil.getFieldValue( signer, "digest" );
// digest.update( srcData, 0, srcData.length );
// byte[] result = new byte[digest.getDigestSize()];
// digest.doFinal(result, 0);
// System.out.println("hash=" + Util.bytes2HexString(result));
// log.info("hash=" + Util.bytes2HexString(result));
signer.update(srcData, 0, srcData.length);
return signer.verifySignature(sign);

View File

@ -69,7 +69,7 @@ public class SM3 {
g = V[6];
h = V[7];
/*System.out.println("IV: ");
/*log.info("IV: ");
System.out.print(Integer.toHexString(a)+" ");
System.out.print(Integer.toHexString(b)+" ");
System.out.print(Integer.toHexString(c)+" ");

View File

@ -2,7 +2,9 @@ package com.sunyard.ssp.utils.sm3;
import com.sunyard.config.security.SM3PasswordEncoder;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SM3Digest
{
/** SM3值的长度 */
@ -175,9 +177,9 @@ public class SM3Digest
String s="";
SM3PasswordEncoder passwordEncoder = new SM3PasswordEncoder();
String encode = passwordEncoder.encode(s);
System.out.println("加密后结果="+encode);
log.info("加密后结果="+encode);
boolean matches = passwordEncoder.matches("123", encode);
System.out.println("校验结果="+matches);
log.info("校验结果="+matches);
}
}

View File

@ -1,5 +1,5 @@
server:
port: 88
port: 89
tomcat:
uri-encoding: UTF-8
threads:
@ -70,16 +70,7 @@ mybatis-plus:
#逻辑删除配置
#logic-delete-value: 1
#logic-not-delete-value: 0
# Swagger界面内容配置
swagger:
title: sspweb API接口文档
description:
version: 1.0.0
termsOfServiceUrl:
contact:
name:
url:
email:
ssp:
token:
# 默认JWT 启用Redis后设置为true后token将存入redis并具有单点登录功能
@ -132,19 +123,16 @@ ignored:
- /ushield/init/bindUPublickey
- /status/set
- /test/setALL
logging:
#logging:
# config: classpath:log4j2.xml
level:
cn.jay.repository: trace
# level:
# org.springframework.web: trace
monitorSwitch:
redis: ${redisMonitorSwitch:true}
db: ${dbMonitorSwitch:true}
scheduler:
cron: 0 0 * * * ?
releaseTime: 1718332531
#redisSyncTask:
# packageName: com.sunyard.ssp.modules.redisSyncTask.task

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--<include resource="org/springframework/boot/logging/logback/base.xml"/>-->
<!-- 定义log文件的目录 -->
<property name="LOG_HOME" value="logs"/>
<!-- 加载 Spring 配置文件信息 -->
<springProperty scope="context" name="applicationName" source="spring.application.name" defaultValue="localhost"/>
<!-- 日志输出格式 -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %X{tl} [%thread] %-5level [%logger{0}:%L]- %msg%n%ex{15}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--日志文件输出格式-->
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
</appender>
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/his/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--单个文件-->
<maxFileSize>200MB</maxFileSize>
<!--文件保存时间(天)-->
<maxHistory>700</maxHistory>
<!--总文件日志最大的大小-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--日志文件输出格式-->
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/his/warn.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--单个文件-->
<maxFileSize>200MB</maxFileSize>
<!--文件保存时间(天)-->
<maxHistory>700</maxHistory>
<!--总文件日志最大的大小-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--日志文件输出格式-->
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/his/error.%d{yyyy-MM-dd }.%i.log</fileNamePattern>
<!--单个文件-->
<maxFileSize>200MB</maxFileSize>
<!--文件保存时间(天)-->
<maxHistory>700</maxHistory>
<!--总文件日志最大的大小-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--日志文件输出格式-->
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<root level="INFO">
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>