最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring aop+反射實(shí)現(xiàn)電話號(hào)加密

 更新時(shí)間:2021年06月05日 09:32:27   作者:來(lái)了我的小老弟  
線上項(xiàng)目涉及大量查詢接口中,存在電話號(hào)明文展示不合規(guī)的問(wèn)題。如果對(duì)每個(gè)接口返回結(jié)果中電話號(hào)相關(guān)字段修改相關(guān)代碼邏輯,則工作量較大花費(fèi)時(shí)間多。因此設(shè)計(jì)電話號(hào)加密注解,減少工作量。

加密算法

為什么需要加密呢?就好比戰(zhàn)爭(zhēng)時(shí)期特工在進(jìn)行傳輸情報(bào)的時(shí)候,如果將情報(bào)明文直接通過(guò)某種媒介傳輸給同盟人員,那么一旦情報(bào)被地方截取,就會(huì)釀成大禍。如果將明文通過(guò)某種加密算法加密成雜亂無(wú)章的密文,即使被敵方截獲,沒(méi)有對(duì)應(yīng)的解密算法,也很難識(shí)別出其中的明文。安全傳輸領(lǐng)域,加密算法是一種很常用的手段,它可以保證數(shù)據(jù)不被竊取和泄漏,還可以保證數(shù)據(jù)的完整性,不被篡改。

常見(jiàn)的加密算法有對(duì)稱加密,非對(duì)稱加密,單向加密(簽名)等分類。其中對(duì)稱加密算法,加密密鑰和解密密鑰是同一個(gè),因此發(fā)送發(fā)和接收方都需要維護(hù)一個(gè)相同的密鑰,如果密鑰要修改,雙方都需要同時(shí)修改。非對(duì)稱加密算法中,發(fā)送發(fā)用公鑰進(jìn)行加密,接收方用私鑰進(jìn)行解密。單向加密算法是對(duì)傳輸?shù)臄?shù)據(jù)生成一個(gè)簽名,通過(guò)這個(gè)簽名來(lái)驗(yàn)證數(shù)據(jù)在傳輸過(guò)程中是否被篡改過(guò),一般是不可逆的。

AES

  • AES 加密算法是一種對(duì)稱加密算,加密密鑰和解密密鑰是同一個(gè)。它采用對(duì)稱分組密碼體制,最少支持長(zhǎng)度為128位的加密。涉及到分組加密,padding填充,初始向量IV,密鑰,四種加密模式。
  • 分組加密就是將原文分割成一段段的分別進(jìn)行加密,每段分組長(zhǎng)度為128位16個(gè)字節(jié),如果最后一組長(zhǎng)度不足128位,則采用padding填充模式將其補(bǔ)齊到128位。然后對(duì)每組進(jìn)行加密,最后組成最終密文。
  • padding填充是為了解決分組后的長(zhǎng)度不足128位的場(chǎng)景。填充模式也有多種不同模式,比如PKCS5, PKCS7和NOPADDING。其中PKSC5是指分組后缺少幾個(gè)字節(jié),就在后面填充幾個(gè)字節(jié)的幾,比如缺少2個(gè)字節(jié),就在后面填充2個(gè)字節(jié)的2。PKCS7是指缺少幾個(gè)字節(jié),就在后面填充幾個(gè)字節(jié)的0,比如缺少5個(gè)字節(jié),就填充5個(gè)字節(jié)的0。NOPADDING模式就是不需要填充。如果最后面剛好是16個(gè)字節(jié)的16,那么解密方不知道是填充數(shù)據(jù)還是真實(shí)數(shù)據(jù),因此會(huì)在后面再補(bǔ)16個(gè)字節(jié)的16來(lái)區(qū)分。
  • 初始向量IV是為了保證數(shù)據(jù)的安全性,如果我們對(duì)同一段內(nèi)容進(jìn)行加密后,所生成的密文應(yīng)該是相同的,那么這樣就很容易通過(guò)密文分析出哪些段是相同的。比如原文分組后成為ABCADE,加密后的密文是GHIGJK,那么很容易看出那兩段內(nèi)容是相同的。第一個(gè)分組在初始加密向量的基礎(chǔ)上進(jìn)行加密,以后的每一個(gè)分組都在前一個(gè)分組加密的結(jié)果為基礎(chǔ)進(jìn)行加密,從而保證了即使相同的原文段,也不會(huì)生成相同的密文段。
  • 密鑰是加密和解密公用的一個(gè),它一般是128位16個(gè)字節(jié)長(zhǎng)度的隨機(jī)字符串,分組后的原文都用同一個(gè)密鑰進(jìn)行加密。
  • 加密模式包含ECB,CBC, CFB, OFB等四種模式。ECB分別對(duì)每個(gè)分組進(jìn)行加密,相同的明文會(huì)被加密成相同的密文。CBC模式會(huì)使用上一段的加密結(jié)果作為加密向量,相同的原文不會(huì)被加密成相同的密文。

MD5

MD5算法是一種不可逆的簽名算法,對(duì)相同的輸入通過(guò)MD5散列函數(shù)處理后,會(huì)輸出相同的信息。因此MD5可以驗(yàn)證傳輸?shù)臄?shù)據(jù)是否有被篡改,但是如果竊密者對(duì)明文進(jìn)行了修改后,再使用MD5算法進(jìn)行散列,接收方將無(wú)法判斷明文已經(jīng)被修改了。一般數(shù)據(jù)庫(kù)存儲(chǔ)用戶密碼會(huì)將密碼使用MD5進(jìn)行處理。

HMAC-MD5

HMAC-MD5由一個(gè)H函數(shù)和一個(gè)密鑰組成,一般我們采用的散列函數(shù)為Md5或者SHA-1。HMAC-MD5算法就是采用密鑰加密+Md5信息摘要的方式形成新的密文。

AOP

眾所周知,AOP(面向切面編程)是Spring一個(gè)重要特性,它將核心關(guān)注點(diǎn)和業(yè)務(wù)邏輯進(jìn)行解耦,將業(yè)務(wù)無(wú)關(guān)的邏輯提取出來(lái)作為公共模塊進(jìn)行處理。它有切點(diǎn),切面,連接點(diǎn),通知的概念。切點(diǎn)就是我們可以織入切面的點(diǎn),切面就是我們要織入的橫切邏輯,通知包含前置通知,后置通知,返回通知,異常通知,環(huán)繞通知等。

1. 引入依賴

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.18</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

2. 業(yè)主信息類、業(yè)主信息服務(wù)類

@Data
@AllArgsConstructor
public class CustomerInfo {

    private String name;

    private String phoneNum;
}

@Service
public class CustomerInfoService {

    @PhoneEncryptionForList(fields = "phoneNum", clazz = CustomerInfo.class)
    public List<CustomerInfo> listCustomerInfo() {
        return Arrays.asList(
                new CustomerInfo("小王", "15112368569"),
                new CustomerInfo("小李", "13652298565"),
                new CustomerInfo("小武", "18965653698"),
                new CustomerInfo("小天", "13192558569")
        );
    }
}

3. 電話號(hào)加密注解,電話號(hào)加密切面類

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PhoneEncryptionForList {

    /**
     * 加密字段
     *
     * @return
     */
    String[] fields();

    /**
     * 加密對(duì)象類型
     *
     * @return
     */
    Class<?> clazz();
}

@Aspect
@Component
public class PhoneEncryptionForListAspect {

    private static final int PHONE_SIZE = 11;

    @AfterReturning(value = "@annotation(com.zzq.spring.phone.encryption.PhoneEncryptionForList)", returning = "result")
    public void doEncrypt(JoinPoint joinPoint, Object result) {
        if (result == null || !(result instanceof List)) {
            System.out.println("result class type is not list, annotation is invalid");
            return;
        }

        List list = (List) result;
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 獲取注解的屬性值
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        PhoneEncryptionForList annotation = method.getAnnotation(PhoneEncryptionForList.class);
        String[] fields = annotation.fields();
        Class<?> clazz = annotation.clazz();

        for (String field : fields) {
            try {
                // 反射獲取實(shí)體類加密字段相應(yīng)的 set 和 get 方法
                char[] chars = field.toCharArray();
                chars[0] = (char) (chars[0] - 32);
                String setMethodName = "set" + new String(chars);
                String getMethodName = "get" + new String(chars);
                Method getMethod = clazz.getDeclaredMethod(getMethodName);
                Method setMethod = clazz.getDeclaredMethod(setMethodName, String.class);

                for (Object obj : list) {
                    doEncryptPhone(getMethod, setMethod, obj);
                }
            } catch (Exception e) {
                System.out.println(field + " encrypt exception, " + e.getMessage());
                continue;
            }
        }
    }

    private static void doEncryptPhone(Method getMethod, Method setMethod, Object obj) throws Exception {
        // 反射調(diào)用 get 方法
        String originalPhone = (String)getMethod.invoke(obj);
        if (!StringUtils.hasText(originalPhone) || originalPhone.length() != PHONE_SIZE) {
            System.out.println("phone field value is blank or formal error");
            return;
        }

        String encryptedPhone = originalPhone.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2");
        // 反射調(diào)用 set 方法
        setMethod.invoke(obj, encryptedPhone);
    }
}

4. 測(cè)試類

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.zzq.spring.phone.encryption")
public class TestApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(TestApplication.class);

        CustomerInfoService customerInfoService = ctx.getBean(CustomerInfoService.class);
        List<CustomerInfo> afterPhoneEncryptCustomerInfos = customerInfoService.listCustomerInfo();

        afterPhoneEncryptCustomerInfos.forEach(customerInfos -> {
            System.out.println(customerInfos);
        });
    }
}

5. 結(jié)果和總結(jié)

該加密注解只簡(jiǎn)單實(shí)現(xiàn)了電話號(hào)加密,注解中還可以新增一些屬性擴(kuò)展注解功能,比如增加加密字段格式加密規(guī)則的正則表達(dá)式的屬性值,這樣加密的字段類型(手機(jī)號(hào)、身份證等)和方式(中間多少位加密、首位加密)就可以根據(jù)具體需求處理。

以上就是Spring aop+反射實(shí)現(xiàn)電話號(hào)加密的詳細(xì)內(nèi)容,更多關(guān)于Spring aop電話號(hào)加密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解SpringBoot中的參數(shù)校驗(yàn)(項(xiàng)目實(shí)戰(zhàn))

    詳解SpringBoot中的參數(shù)校驗(yàn)(項(xiàng)目實(shí)戰(zhàn))

    這篇文章主要介紹了SpringBoot中的參數(shù)校驗(yàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 解決SpringBoot引用別的模塊無(wú)法注入的問(wèn)題

    解決SpringBoot引用別的模塊無(wú)法注入的問(wèn)題

    這篇文章主要介紹了解決SpringBoot引用別的模塊無(wú)法注入的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java精品項(xiàng)目瑞吉外賣之員工信息管理篇

    Java精品項(xiàng)目瑞吉外賣之員工信息管理篇

    這篇文章主要為大家詳細(xì)介紹了java精品項(xiàng)目-瑞吉外賣訂餐系統(tǒng),此項(xiàng)目過(guò)大,分為多章獨(dú)立講解,本篇內(nèi)容為員工信息分頁(yè)查詢與啟用或禁用員工狀態(tài),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Java 讀取圖片的mimeType的方法

    Java 讀取圖片的mimeType的方法

    本篇文章主要介紹了Java 讀取圖片的mimeType的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • SpringBoot快速整合SpringSecurity的詳細(xì)步驟(新手都會(huì)!)

    SpringBoot快速整合SpringSecurity的詳細(xì)步驟(新手都會(huì)!)

    日 Spring Security 是針對(duì)Spring項(xiàng)目的安全框架,也是Spring Boot底層安全模塊默認(rèn)的技術(shù)選型,他可以實(shí)現(xiàn)強(qiáng)大的Web安全控制,下面這篇文章主要給大家介紹了關(guān)于SpringBoot快速整合SpringSecurity的詳細(xì)步驟,需要的朋友可以參考下
    2023-03-03
  • Springboot發(fā)送post請(qǐng)求的幾種方式總結(jié)

    Springboot發(fā)送post請(qǐng)求的幾種方式總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Springboot發(fā)送post請(qǐng)求的幾種方式,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以了解一下
    2024-01-01
  • Fastjson 常用API介紹及下載地址(推薦)

    Fastjson 常用API介紹及下載地址(推薦)

    Fastjson是一個(gè)Java語(yǔ)言編寫的高性能功能完善的JSON庫(kù)。接下來(lái)通過(guò)本文給大家分享Fastjson 常用API介紹及下載地址,感興趣的朋友一起看看吧
    2017-11-11
  • Java職責(zé)鏈模式的深入了解

    Java職責(zé)鏈模式的深入了解

    這篇文章主要為大家介紹了Java職責(zé)鏈模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • java圖形界面之布局設(shè)計(jì)

    java圖形界面之布局設(shè)計(jì)

    這篇文章主要介紹了java圖形界面之布局設(shè)計(jì)的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • 面向切面的Spring通過(guò)切點(diǎn)來(lái)選擇連接點(diǎn)實(shí)例詳解

    面向切面的Spring通過(guò)切點(diǎn)來(lái)選擇連接點(diǎn)實(shí)例詳解

    這篇文章主要為大家介紹了面向切面的Spring通過(guò)切點(diǎn)來(lái)選擇連接點(diǎn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10

最新評(píng)論

和静县| 曲阜市| 罗定市| 洛隆县| 美姑县| 七台河市| 贡山| 平陆县| 二连浩特市| 宁德市| 城固县| 乌鲁木齐市| 景泰县| 金坛市| 墨玉县| 新昌县| 聊城市| 道孚县| 南平市| 大理市| 平陆县| 无极县| 崇明县| 惠来县| 金塔县| 大连市| 六盘水市| 西青区| 洛宁县| 铁岭县| 金溪县| 兴城市| 和田市| 陆丰市| 晋宁县| 禹城市| 桃园市| 博客| 凌海市| 冀州市| 永春县|