对返回参数进行加密可以增强数据传输的安全性,以防止敏感数据被截获或篡改。
枚举类
用于区分数据的加密方式
/**
* 加密方式
* @Author RainCity
* @Date 2023-04-12 17:00:53
*/
public enum EncryptMode {
/**
* BASE64
*/
BASE64,
/**
* AES
*/
AES,
/**
* RSA
*/
RSA,
}
注解
用于方法上,标识此方法的返回参数需要加密后返回,默认BASE64加密
/**
* @Author RainCity
* @Date 2022-08-29 08:49:23
* @Desc 用于方法,参数加密注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EncryptResponse {
EncryptMode encryptMode() default EncryptMode.BASE64;
}
ResponseBodyAdvice
处理参数的加密
/**
* @Author RainCity
* @Date 2023-04-12 13:44:18
* @Desc 返回参数加密
*/
@ControllerAdvice
public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
private static final Logger log = LoggerFactory.getLogger(EncryptResponseAdvice.class);
private static final ThreadLocal<Boolean> ENCRYPT_LOCAL = new ThreadLocal<>();
@Override
public boolean supports(MethodParameter returnParameter, Class<? extends HttpMessageConverter<?>> converterType) {
return Objects.requireNonNull(returnParameter.getMethod()).isAnnotationPresent(EncryptResponse.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
Boolean status = ENCRYPT_LOCAL.get();
if (null != status && !status) {
ENCRYPT_LOCAL.remove();
return null;
}
try {
String content = JSON.toJSONString(body);
// 判断加密类型
EncryptResponse encryptResponse = returnType.getExecutable().getAnnotation(EncryptResponse.class);
// AES PKCS7Padding 加密
// 详情见 https://blog.csdn.net/weixin_43645266/article/details/131162492?spm=1001.2014.3001.5501
if(EncryptMode.AES.equals(encryptResponse.encryptMode())){
return Aes.encrypt(content);
}
// RSA 加密
// 详情见 https://blog.csdn.net/weixin_43645266/article/details/131182615?spm=1001.2014.3001.5501
if(EncryptMode.RSA.equals(encryptResponse.encryptMode())){
return Rsa.encrypt(content);
}
// BASE64 加密
return Base64.getEncoder().encodeToString(content.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
log.error("Encrypted data exception", e);
return null;
}
}
}
使用ResponseBodyAdvice对返回结果进行加密或压缩等操作可以有效提高数据传输的安全性和效率。但需要注意的是,如果对返回结果进行加密操作,客户端需要使用对应的解密算法对返回结果进行解密操作后才能正确地使用数据。