使用自定义注解实现加解密及脱敏方式

网友投稿 839 2022-11-14

使用自定义注解实现加解密及脱敏方式

使用自定义注解实现加解密及脱敏方式

目录自定义注解实现加解密及脱敏定义自定义注解构造AOP逻辑测试脱敏逻辑自定义一种字符串的加密与解密

自定义注解实现加解密及脱敏

定义自定义注解

@Documented

@Target({ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)

@Order(Ordered.HIGHEST_PRECEDENCE)

public @interface PrivateData {

}

@Documented

@Target({ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Order(Ordered.HIGHEST_PRECEDENCE)

public @interface PrivateDataMethod {

}

首先定义两个自定义注解,privateData和privateDataMethod,分别将@Target属性定义为FIELD和METHOD。

构造AOP逻辑

申明一个切入点

@Pointcut("@annotation(com.max.base.services.annotation.PrivateDataMethod)")

public void annotationPointCut() {

}

对所有添加@privateDataMethod注解的方法进行切入。

申明通知

@Around("annotationPointCut()")

public Object around(ProceedingJoinPoint joinPoint) {

Object responseObj = null;

try {

Object[] request = joinPoint.getArgs();

for (Object object : request) {

if (object instanceof Collection) {

Collection collection = (Collection) object;

collection.forEach(var -> {

try {

handleEncrypt(var);

} catch (IllegalAccessException e) {

e.printStackTrace();

}

});

} else {

handleEncrypt(object);

}

}

responseObj = joinPoint.proceed();

if (responseObj instanceof Collection) {

Collection collection = (Collection) responseObj;

collection.forEach(var -> {

try {

handleDecrypt(var);

} catch (IllegalAccessException e) {

e.printStackTrace();

}

});

} else {

handleDecrypt(responseObj);

}

} catch (Throwable throwable) {

throwable.printStackTrace();

log.error("SecureFieldAop 异常{}", throwable);

}

return responseObj;

}

申明Aroud通知,对于方法输入输出的对象进行判断,如果是非集合对象则直接进行加解密操作,否则则拆分集合,逐一操作

处理加解密

/**

* 处理加密

* @param requestObj

*/

private void handleEncrypt(Object requestObj) throws IllegalAccessException {

if (Objects.isNull(requestObj)) {

return;

}

Field[] fields = requestObj.getClass().getDeclaredFields();

for (Field field : fields) {

boolean hasSecureField = field.isAnnotationPresent(PrivateData.class);

if (hasSecureField) {

Boolean accessible = field.isAccessible();

if (!accessible) {

field.setAccessible(true);

}

ZeFBfZF String plaintextValue = (String) fieldhttp://.get(requestObj);

String encryptValue = AseUtil.encrypt(plaintextValue, secretKey);

field.set(requestObj, encryptValue);

if (!accessible) {

field.setAccessible(false);

}

}

}

}

通过反射获取对象的Field列表,对于拥有@PrivateData注解的字段执行**encryptValue()**方法并用加密后的字符串覆盖原字段。

解密逻辑与加密类似,不做赘述。

测试

标识insert()方法为需要加密的方法

public interface CmTenantMapper {

int deleteByPrimaryKey(Long id);

@PrivateDataMethod

int insert(CmTenant record);

int insertSelective(CmTenant record);

CmTenant selectByPrimaryKey(Long id);

int updateByPrimaryKeySelective(CmTenant record);

int updateByPrimaryKey(CmTenant record);

}

对传入对象中需要加密的字段添加注解

public class CmTenant {

private Long id;

private String tenantId;

@PrivateData

private String tenantName;

private String createBy;

private Date createDate;

private String updateBy;

private Date updateDate;

private String remarks;

private Byte delFlag;

//set get...

调用insert方法查看数据保存结果

传入对象

{

"createBy": "可乐可不乐",

"delFlag": "NOTDELETE",

"remarks": "测试加密",

"tenantId": "996",

"tenantName": "椅子团队出品",

"updateBy": "可乐可不乐"

}

数据库保存对象

解密测试不做注释,大家自行尝试

脱敏逻辑

脱敏逻辑与加解密基本一致,需要注意的一点是脱敏的注解需要添加type类型

@Documented

@Target({ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)

@Order(Ordered.HIGHEST_PRECEDENCE)

public @interface MaskingField {

MaskingTypeEnum type();

}

在MaskingTypeEnum中定义脱敏的分类

public enum MaskingTypeEnum {

/*身份证号码*/

ID_CARD,

/*手机号码*/

PHONE,

/*地址*/

ADDRESS,

/*姓名*/

NAME

}

在使用是MaskingTypeEnum时标识字段的类型

@MaskingField(type = MaskingTypeEnum.NAME)

private String cpName;

自定义一种字符串的加密与解密

package com.hanqi.lianxi;

package com.hanqi.lianxi;

import java.util.Scanner;

public class jiamiqi

{

public static http://vZeFBfZFoid main(String[] args)

{

//输入解密前的内容

Scanner sc = new Scanner(System.in);

System.out.println("请输入需要解码的信件内容");

String tex = sc.nextLine();

//用替换的方式实现解密

System.out.print("解密后的内容为:"+tex.replaceAll("A", "c").replaceAll("B", "d").replaceAll("C", "e").replaceAll("D", "f").replaceAll("E", "g").replaceAll("F", "h").replaceAll("G", "i").replaceAll("H", "j").replaceAll("I", "k").replaceAll("J", "l").replaceAll("K", "m").replaceAll("L", "n").replaceAll("M", "o").replaceAll("N", "p").replaceAll("O", "q").replaceAll("P", "r").replaceAll("Q", "s").replaceAll("R", "t").replaceAll("S", "u").replaceAll("T", "v").replaceAll("U", "w").replaceAll("V", "x").replaceAll("W", "y").replaceAll("X", "z").replaceAll("Y", "a").replaceAll("Z", "b"));

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:git推送本地分支到远程分支
下一篇:Redis 集群
相关文章

 发表评论

暂时没有评论,来抢沙发吧~