根据业务需求,要求多部分字段,进行加解密,想到实现方式,就是通过自定义的注解+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 字节)
示例:
 新增数据:
 

 查询数据:
 



















