自定义注解,实现字段加密解密

根据业务需求,要求多部分字段,进行加解密,想到实现方式,就是通过自定义的注解+AOP来实现
首先新建一个注解,注意ElementType.FIELD类型,说明这个注解只能作用在字段上

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedEncrypt {
}

在新建一个切面类

@Aspect
@Component
public class EncryptionAspect {

    @Resource
    private EncryptionImpl encryptionService;

    //定义切点
    @Pointcut("within(com.bosssoft..*.*impl.*) && execution(* *(..))")
    public void pointCut(){}

    @Around("pointCut()")
    public Object encryptDecrypt(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        Object entity = args[0];

        // 加密前
        encryptFieldsBeforeSave(entity);

        // 执行方法
        Object result = joinPoint.proceed(args);

        // 解密后
        if (result != null) {
            decryptFieldsAfterQuery((Object) result);
        }

        return result;
    }

    private void encryptFieldsBeforeSave(Object entity) throws IllegalAccessException {
        Class<?> clazz = entity.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(NeedEncrypt.class)) {
                field.setAccessible(true);
                String value = (String) field.get(entity);
                if (value != null) {
                    String encryptedValue = encryptionService.encrypt(value);
                    field.set(entity, encryptedValue);
                }
            }
        }
    }

    private void decryptFieldsAfterQuery(Object entity) throws IllegalAccessException {
        Class<?> clazz = entity.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(NeedEncrypt.class)) {
                field.setAccessible(true);
                String value = (String) field.get(entity);
                if (value != null) {
                    String decryptedValue = encryptionService.decrypt(value);
                    field.set(entity, decryptedValue);
                }
            }
        }
    }
}

这个类中定义了切面,包含所有的实现类,以及实现类中所有的方法

下一步创建这个切面类的实现类,用来实现一些方法,比如:具体的加解密算法
本加密算法采用的是AES

@Component
public class EncryptionImpl {
    private static final String SECRET_KEY = "your_secret_key";
    private static final String ALGORITHM = "AES";

    public String encrypt(String valueToEncrypt) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedValue = cipher.doFinal(valueToEncrypt.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedValue);
        } catch (Exception e) {
            throw new RuntimeException("Encryption failed", e);
        }
    }

    public String decrypt(String encryptedValue) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decodedValue = Base64.getDecoder().decode(encryptedValue);
            byte[] decryptedValue = cipher.doFinal(decodedValue);
            return new String(decryptedValue, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("Decryption failed", e);
        }
    }
}

注意的AES算法的密钥长度, 必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)

示例:
新增数据:
在这里插入图片描述

在这里插入图片描述
查询数据:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值