feat(data): 添加数据加解密功能
- 新增 AesEncryptionUtil 类实现 AES 加解密- 添加 EncryptionAspect 切面处理加密请求 - 创建 EncryptionMapping 注解用于标记加密接口 -定义 EncryptionReqDto 请求 DTO- 生成 UUID 工具类 - 标记旧的 AESEncryptionUtil 类为过时liujun-yunwei
parent
1816b13dc0
commit
ed544c3c9f
|
@ -0,0 +1,41 @@
|
|||
package com.zcloud.modules.data.aop;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* @author fangjiakai
|
||||
* @date 2024/7/16 17:34
|
||||
*/
|
||||
public class AesEncryptionUtil {
|
||||
private static final String ALGORITHM = "AES/ECB/PKCS5Padding"; // PKCS5Padding在Java中等同于PKCS7Padding
|
||||
private static final String SECRET_KEY = "23b174c252ffe72b"; // 必须是16, 24, or 32 bytes long for AES-128, AES-192 or AES-256
|
||||
|
||||
public static String encrypt(String key , String plainText) throws Exception {
|
||||
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
|
||||
|
||||
byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
|
||||
return Base64.getEncoder().encodeToString(encrypted);
|
||||
}
|
||||
public static String decrypt(String encryptedText) throws Exception {
|
||||
return decrypt(encryptedText,SECRET_KEY);
|
||||
}
|
||||
|
||||
public static String decrypt(String key,String encryptedText) throws Exception {
|
||||
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec);
|
||||
|
||||
byte[] decodedBytes = Base64.getDecoder().decode(encryptedText);
|
||||
byte[] decrypted = cipher.doFinal(decodedBytes);
|
||||
return new String(decrypted, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.zcloud.modules.data.aop;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.zcloud.common.utils.R;
|
||||
import com.zcloud.modules.data.dto.system.EncryptionReqDto;
|
||||
import lombok.extern.java.Log;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
@Log
|
||||
public class EncryptionAspect {
|
||||
|
||||
@Around("@annotation(EncryptionMapping)")
|
||||
public Object decryptAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
// 获取请求参数(假设参数为JSON字符串)
|
||||
Object[] args = joinPoint.getArgs();
|
||||
String encryptedData = (String) args[0];
|
||||
if (encryptedData == null){
|
||||
return R.error("参数不能为空");
|
||||
}
|
||||
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if (attributes == null){
|
||||
return R.error("系统异常:1000");
|
||||
}
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
String headerValue = request.getHeader("");
|
||||
EncryptionReqDto reqDto = JSONObject.parseObject(encryptedData, EncryptionReqDto.class);
|
||||
if (StringUtils.isEmpty(reqDto.getData())){
|
||||
return R.error("系统异常:2000");
|
||||
}
|
||||
// 解密请求参数
|
||||
String decryptedData = AesEncryptionUtil.decrypt(reqDto.getData());
|
||||
// 替换原始参数为解密后的数据
|
||||
args[0] = decryptedData;
|
||||
return joinPoint.proceed(args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.zcloud.modules.data.aop;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 用于加解密的接口注解
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @interface EncryptionMapping {
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#name}.
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#value}.
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#path}.
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] path() default {};
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#params}.
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] params() default {};
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#headers}.
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] headers() default {};
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#consumes}.
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] consumes() default {};
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#produces}.
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] produces() default {};
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.zcloud.modules.data.dto.system;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
public class EncryptionReqDto {
|
||||
|
||||
@NotBlank(message = "数据不能为空")
|
||||
private String data;
|
||||
}
|
|
@ -25,6 +25,7 @@ public final class AESEncryptionUtil {
|
|||
*
|
||||
* @return AES 秘钥
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getKey() {
|
||||
return Stream.generate(() -> Character.toString(CHAR_BASE[(int) (Math.random() * CHAR_BASE.length)]))
|
||||
.limit(16).collect(Collectors.joining());
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.zcloud.modules.util;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 说明:生成UUID(32位不重复的字符串)
|
||||
|
||||
|
||||
*/
|
||||
public class UuidUtil {
|
||||
|
||||
public static String get32UUID() {
|
||||
return UUID.randomUUID().toString().trim().replaceAll("-", "");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue