溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

springboot中如何使用自定義注解實現(xiàn)加解密及脫敏方式

發(fā)布時間:2021-12-18 13:02:36 來源:億速云 閱讀:837 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹springboot中如何使用自定義注解實現(xiàn)加解密及脫敏方式,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

    自定義注解實現(xiàn)加解密及脫敏

    定義自定義注解

    @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。

    構(gòu)造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);
                    }
                    String plaintextValue = (String) field.get(requestObj);
                    String encryptValue = AseUtil.encrypt(plaintextValue, secretKey);
                    field.set(requestObj, encryptValue);
                    if (!accessible) {
                        field.setAccessible(false);
                    }
                }
            }
        }

    通過反射獲取對象的Field列表,對于擁有@PrivateData注解的字段執(zhí)行**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...

    調(diào)用insert方法查看數(shù)據(jù)保存結(jié)果

    傳入對象

    {
      "createBy": "可樂可不樂",
      "delFlag": "NOTDELETE",
      "remarks": "測試加密",
      "tenantId": "996",
      "tenantName": "椅子團隊出品",
      "updateBy": "可樂可不樂"
    }

    數(shù)據(jù)庫保存對象

    解密測試不做注釋,大家自行嘗試

    脫敏邏輯

    脫敏邏輯與加解密基本一致,需要注意的一點是脫敏的注解需要添加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 void main(String[] args)
        {
            //輸入解密前的內(nèi)容
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入需要解碼的信件內(nèi)容");
        String tex = sc.nextLine();
            //用替換的方式實現(xiàn)解密
        System.out.print("解密后的內(nèi)容為:"+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"));    
        }
    }

    springboot中如何使用自定義注解實現(xiàn)加解密及脫敏方式

    springboot中如何使用自定義注解實現(xiàn)加解密及脫敏方式

    以上是“springboot中如何使用自定義注解實現(xiàn)加解密及脫敏方式”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI