DESC结合Aop对铭感数据注解式加解密

本文介绍了如何结合DESC加密算法和Spring AOP来实现在Java中对敏感数据进行注解式的自动加解密。主要包括:引入AOP依赖,创建自定义注解,编写AOP切面处理注解,以及DESC加解密工具类的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.引入aop依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
  </dependency>

2.自定义注解,使用Aspect 对传入数据加密,出参解密

/**
 * @author zhenglong
 * @Description: DESC加解密字段
 * @Date 2020/11/26 9:32
 */

@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface EnDeField {
    /**
     * 1 desc 、 2 md5和desc
     * @return
     */
    int value() default 1;
}

3.编写Aop,实现注解类添加到方法和对应的字段上,可以进行自动加解密

/**
 * @author zhenglong
 * @Description: 安全字段加密解密切面
 * @Date 2020/11/26 0:12
 */
@Aspect
@Component("EndeFieldAspect")
public class EnDeFieldAop {
    Logger log = LoggerFactory.getLogger(EnDeFieldAop.class);

//    @Pointcut("execution(* com.csair.cargo.delivery.exchange.controller.*.*(..))  ")
//    public void annotationPointCut() {
//    }


    @Around("execution(* com.csair.cargo.delivery.exchange.controller.*.*(..)) && @annotation(enDeField)")
    public Object around(ProceedingJoinPoint joinPoint,EnDeField enDeField) {
        Object responseObj = null;
        try {
            Object requestObj = null;
            try {
                requestObj = joinPoint.getArgs()[0];
            } catch (Exception e) {
            }
            handleEncrypt(requestObj);
            responseObj = joinPoint.proceed();
            handleDecrypt(responseObj);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            log.info("加解密出现问题了", e.getMessage());
        } catch (Throwable throwable) {
            log.info("加解密出现问题了", throwable.getCause());
//            throwable.printStackTrace();
        }
        return responseObj;
    }

    /**
     * 处理加密
     *
     * @param requestObj
     */
    private void handleEncrypt(Object requestObj) throws Exception {
        if (Objects.isNull(requestObj)) {
            return;
        }
  
        authField(requestObj, 1);

    }


    /**
     * 处理解密
     *
     * @param responseObj
     */
    private Object handleDecrypt(Object responseObj) throws Exception {
        if (Objects.isNull(responseObj)) {
            return null;
        }
        @SuppressWarnings("rawtypes")
        ExecuteResult executeResult = (ExecuteResult) responseObj;
        Object o = executeResult.getResult();
        if (o instanceof PageResult) {
            @SuppressWarnings("rawtypes")
            PageResult pageResult = (PageResult) o;
            List list = pageResult.getData();
            forList(list, 2);
        } else if (o instanceof Collection) {
            List list = (List) o;
            forList(list, 2);
        } else {
            authField(o, 2);
        }
        return responseObj;
    }

    private Object forList(List list, Integer flag) throws Exception {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        for (Object r : list) {
            authField(r, flag);
        }
        return list;
    }

    /**
     * 公共加解密方法
     *
     * @param o
     * @throws Exception
     */
    private void authField(Object o, Integer flag) throws Exception {
        Field[] fields = o.getClass().getDeclaredFields();
        for (Field field : fields) {
            boolean hasSecureField = field.isAnnotationPresent(EnDeField.class);
            if (hasSecureField) {
                field.setAccessible(true);
                String encryptValue = (String) field.get(o);
                //int value = field.getAnnotation(EnDeField.class).value();
                String plaintextValue = null;
                if (encryptValue == null) {
                    continue;
                }
                if (flag == 1) {
                    plaintextValue = DescUtils.encrypt(encryptValue);
                } else {
                    plaintextValue = DescUtils.decrypt(encryptValue);
                }
                field.set(o, plaintextValue);
            }
        }
    }
}

4.附上DESC根据公钥和向量加解密工具类

/**
 * @author zhenglong
 * @Description: DESC加解密utils
 * @Date 2020/11/25 19:17
 */
public class DescUtils {

    /**
     * 字节数组转16进制
     * @param bytes 需要转换的byte数组
     * @return  转换后的Hex字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if(hex.length() < 2){
                sb.append(0);
            }
            sb.append(hex);
        }
        return sb.toString();
    }
    /**
     * 解密数据
     * @param message
     * @return
     * @throws Exception
     */
    public static String decrypt(String message) throws Exception {
        // 传入加密串,转成bash64字符串
        byte[] bytes = Base64.decodeBase64(message);
        // 传入byte数组常量,返回16进制字符串,并全部转大写,得到byte数组常量的16进制大写字符串
        String pkey = bytesToHex(DescConstant.key).toUpperCase();
        
        DESKeySpec desKeySpec = new DESKeySpec(pkey.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DescConstant.desc);
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(DescConstant.ivKey);
        Cipher cipher = Cipher.getInstance(DescConstant.descFlag);

        cipher.init(Cipher.DECRYPT_MODE, secretKey,iv);
        byte[] retByte = cipher.doFinal(bytes);
        return new String(retByte, DescConstant.encode).trim();
    }

    /**
     * 加密数据
     * @param message
     * @return
     * @throws Exception
     */

    public static String encrypt(String message) throws Exception {
        Cipher cipher = Cipher.getInstance(DescConstant.descFlag );
        String pkey = bytesToHex(DescConstant.key).toUpperCase();
        DESKeySpec desKeySpec = new DESKeySpec(pkey.getBytes());

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DescConstant.desc);
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(DescConstant.ivKey);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey,iv);

        byte[] bytes = cipher.doFinal(message.getBytes(DescConstant.encode));

        return Base64.encodeBase64String(bytes);
    }

    /**
     * Hex字符串转byte
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte
     */
    public static byte hexToByte(String inHex){
        return (byte)Integer.parseInt(inHex,16);
    }


 
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值