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 秘钥
|
* @return AES 秘钥
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String getKey() {
|
public static String getKey() {
|
||||||
return Stream.generate(() -> Character.toString(CHAR_BASE[(int) (Math.random() * CHAR_BASE.length)]))
|
return Stream.generate(() -> Character.toString(CHAR_BASE[(int) (Math.random() * CHAR_BASE.length)]))
|
||||||
.limit(16).collect(Collectors.joining());
|
.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