feat(data): 添加数据加解密功能

- 新增 AesEncryptionUtil 类实现 AES 加解密- 添加 EncryptionAspect 切面处理加密请求
- 创建 EncryptionMapping 注解用于标记加密接口
-定义 EncryptionReqDto 请求 DTO- 生成 UUID 工具类
- 标记旧的 AESEncryptionUtil 类为过时
liujun-yunwei
liujun 2025-06-26 08:31:30 +08:00
parent 1816b13dc0
commit ed544c3c9f
6 changed files with 177 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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 {};
}

View File

@ -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;
}

View File

@ -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());

View File

@ -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("-", "");
}
}