欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實(shí)現(xiàn)MD5加鹽算法的示例代碼

 更新時(shí)間:2025年03月30日 15:46:16   作者:一只愛打拳的程序猿  
加鹽算法是一種用于增強(qiáng)密碼安全性的技術(shù),本文主要介紹了SpringBoot實(shí)現(xiàn)MD5加鹽算法的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、什么是加鹽算法

加鹽算法是一種用于增強(qiáng)密碼安全性的技術(shù)。這種技術(shù)通過在密碼存儲過程中添加一個(gè)隨機(jī)生成的鹽值(salt),來增加密碼被破解的難度。舉個(gè)例子:

在日常生活中,做菜是生活中的基本操作。炒青菜餐桌中必備的一道菜,不同的人炒青菜放鹽的程度是不同的,換句話來說不同的人炒同一種菜放鹽的多與少是一種隨機(jī)的操作。因此,在注冊賬號時(shí),不同用戶在注冊時(shí)難免會使用相同的密碼。加鹽算法會根據(jù)不同的用戶生成一串隨機(jī)的字符串與用戶所輸入的密碼進(jìn)行結(jié)合生成一個(gè)最終的結(jié)果值,而這個(gè)最終值得到的就是加密后的密碼。

具體來說,加鹽加密的過程如下:

生成鹽值:后端在存儲一個(gè)密碼時(shí),首先會隨機(jī)生成一個(gè)鹽值。這個(gè)鹽值是一個(gè)隨機(jī)字符串,用于增加密碼的復(fù)雜性。

結(jié)合鹽值和密碼:將生成的鹽值和用戶輸入的密碼進(jìn)行有規(guī)則的結(jié)合,通常是將鹽值附加在密碼的前面或后面,或者通過其他方式進(jìn)行組合。

加密處理:將結(jié)合后的數(shù)據(jù)使用加密算法進(jìn)行加密。常見的加密算法包括MD5、SHA-256等。在Spring Security中,還可以使用更強(qiáng)大的加密方式,如BCrypt。本期講解使用MD5。

存儲加密后的數(shù)據(jù)和鹽值:將加密后的數(shù)據(jù)和鹽值按照一定規(guī)則組合起來,并存儲在數(shù)據(jù)庫中。通常,鹽值會被保存在與加密密碼相同的記錄中,以便在驗(yàn)證用戶密碼時(shí)使用。

二、如何實(shí)現(xiàn)加鹽算法

2.1 加鹽算法代碼實(shí)現(xiàn)

首先,我們要了解到:

生成一個(gè)隨機(jī)鹽值可使用 UUID ,UUID 是一個(gè)128比特的數(shù)值,通常由 32 個(gè) 16 進(jìn)制數(shù)字組成,并以連字號分為五段,例如:550e8400-e29b-41d4-a716-446655440000,因此可使用 replace 方法去除 

生成一個(gè) MD5 散列值,可使用 DigestUtils類 中的 .md5DigestAsHex 方法將生成的隨機(jī)鹽值 salt 和 password 結(jié)合,并通過 .getBytes 將結(jié)合后的字符串轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組即 .getBytes(StandardCharsets.UTF_8) 。

此外需要注意的是:

  • MD5(Message-Digest Algorithm 5)是一種廣泛使用的散列函數(shù),可以產(chǎn)生一個(gè)128位(16字節(jié))的散列值,通常表示為32位的十六進(jìn)制數(shù)。
  • md5DigestAsHex 是 DigestUtils 類中的一個(gè)靜態(tài)方法。這個(gè)方法接受一個(gè)字節(jié)數(shù)組作為輸入,計(jì)算其MD5散列值,并將結(jié)果轉(zhuǎn)換為十六進(jìn)制字符串。
  • StandardCharsets.UTF_8 是一個(gè)表示UTF-8字符集的常量,它指定了字符串到字節(jié)數(shù)組的編碼方式。

代碼實(shí)現(xiàn):

/**
 * 加密工具類
 */
public class PasswordUtils {
    public static String encrypt(String password){
        // 1.鹽值
        String salt = UUID.randomUUID().toString().replace("-","");
        // 2.將鹽值+密碼進(jìn)行 md5 得到最終密碼
        String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
        // 3.將鹽值和最終密碼返回
        return salt+"$"+finalPassword;
    }


    /**
     * 加鹽驗(yàn)證
     * @param password 待驗(yàn)證的密碼
     * @param dbPassword 數(shù)據(jù)庫中的密碼:鹽值$最終密碼
     * @return
     */
    public static boolean decrypt(String password,String dbPassword) {
        if(!StringUtils.hasLength(password) || !StringUtils.hasLength(dbPassword)
        || dbPassword.length() != 65) {
            return false;
        }
        // 1.得到鹽值
        String[] dbPasswordArray = dbPassword.split("\\$") ;
        if (dbPasswordArray.length != 2) {
            return false;
        }
        //鹽值
        String salt = dbPasswordArray[0];
        //最終正確密碼
        String dbFinalPassword = dbPasswordArray[1];
        // 2.加密待驗(yàn)證的密碼
        String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
        // 3.對比
        if (finalPassword.equals(dbFinalPassword)) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        // 得到鹽值和最終密碼一共65位
        System.out.println(encrypt("111"));
    }
}

在該類中生成一個(gè) main 方法,測試最后生成的字符串符不符合預(yù)期,輸出結(jié)果:

將上述的字符串,定義為一個(gè)字符串,驗(yàn)證是否加密成功。 

    public static void main(String[] args) {
/*        // 得到鹽值和最終密碼一共65位
        System.out.println(encrypt("111"));*/
        String dbPassword = "0f0d62e88c6c41dc83163e2813147111$b7321a14e1e5f3360a0d0d59e2b3cd6e";
        System.out.println("當(dāng)密碼為123時(shí):"+decrypt("123",dbPassword));
        System.out.println("當(dāng)密碼為111時(shí):"+decrypt("111",dbPassword));
    }

 

2.2 注冊頁面中進(jìn)行密碼加鹽

    /**
     * 注冊
     * @param userinfo
     * @return
     */
    @RequestMapping("/reg")
    public ResultAjax reg(Userinfo userinfo) {
       // 1.校驗(yàn)參數(shù)
        if (userinfo == null || !StringUtils.hasLength(userinfo.getUsername()) ||
        !StringUtils.hasLength(userinfo.getPassword())) {
            return ResultAjax.fail(-1,"異常");
        }
        // 實(shí)現(xiàn)密碼加鹽
        userinfo.setPassword(PasswordUtils.encrypt(userinfo.getPassword()));
        // 2.請求接口 service 進(jìn)行添加接口
        int ret = userService.reg(userinfo);
        // 3.將結(jié)果返回給前端
        return ResultAjax.success(ret);
    }

2.3 登錄頁面進(jìn)行加鹽的解密

/**
     * 登錄
     * @param userinfoVO
     * @return
     */
    @RequestMapping("/login")
    public ResultAjax login(UserinfoVO userinfoVO, HttpServletRequest request) {
        // 1.參數(shù)校驗(yàn)
        if (userinfoVO == null || !StringUtils.hasLength(userinfoVO.getUsername())
                || !StringUtils.hasLength(userinfoVO.getPassword())) {
            // 非法登錄
            return ResultAjax.fail(-1,"非法登錄!");
        }
        // 2.根據(jù)用戶名查詢對象,判斷用戶名是否錯誤
        Userinfo userinfo = userService.getUserByName(userinfoVO.getUsername());
        if (userinfo == null && userinfo.getId() == 0) {
            return ResultAjax.fail(-2,"賬號或密碼錯誤!");
        }
        // 3.使用對象中的密碼和輸入的密碼進(jìn)行對比,判斷密碼是否錯誤
        // 加鹽解密
        if (!PasswordUtils.decrypt(userinfoVO.getPassword(),userinfo.getPassword())) {
            return ResultAjax.fail(-2,"賬號或密碼錯誤!");
        }
        // 4.成功后將對象存儲到 session 中
        HttpSession session = request.getSession();
        session.setAttribute(ApplicationVariable.SESSION_USERINFO_KEY,userinfo);
        // 5.結(jié)果返回給用戶
        return ResultAjax.success(1);
    }

 此時(shí)查詢數(shù)據(jù)庫中,只有一條數(shù)據(jù),下面再注冊一個(gè)用戶,觀察是否生成密碼。

2.4 注冊和登錄

注冊頁面

 輸入用戶名 lisi 和密碼 123 后,提示注冊成功。

在數(shù)據(jù)中查詢對應(yīng)的數(shù)據(jù),驗(yàn)證密碼 123 被加秘為一大串字符串。

再來到登錄頁面,輸入用戶名 lisi 和密碼 123,提示登陸成功。 

跳轉(zhuǎn)到個(gè)人頁面。

注冊頁面和登錄頁面的講解和源碼在前兩篇博客中已有詳細(xì)的講解,感興趣可以去看看。

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)MD5加鹽算法的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot MD5加鹽算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot淺析安全管理之Shiro框架

    SpringBoot淺析安全管理之Shiro框架

    安全管理是軟件系統(tǒng)必不可少的的功能。根據(jù)經(jīng)典的“墨菲定律”——凡是可能,總會發(fā)生。如果系統(tǒng)存在安全隱患,最終必然會出現(xiàn)問題,這篇文章主要介紹了SpringBoot安全管理Shiro框架的使用
    2022-08-08
  • springboot的實(shí)體類字段校驗(yàn)的分組校驗(yàn)具體實(shí)現(xiàn)步驟

    springboot的實(shí)體類字段校驗(yàn)的分組校驗(yàn)具體實(shí)現(xiàn)步驟

    分組校驗(yàn)允許在不同場景下對同一實(shí)體類應(yīng)用不同的校驗(yàn)規(guī)則,通過定義分組接口、在實(shí)體類和Controller中指定分組,以及全局異常處理,可以靈活控制校驗(yàn)規(guī)則,本文介紹springboot的實(shí)體類字段校驗(yàn)的分組校驗(yàn),感興趣的朋友一起看看吧
    2025-03-03
  • 基于Java實(shí)現(xiàn)XML文件的解析與更新

    基于Java實(shí)現(xiàn)XML文件的解析與更新

    配置文件可以有很多種格式,包括?INI、JSON、YAML?和?XML。每一種編程語言解析這些格式的方式都不同。本文將通過Java語言實(shí)現(xiàn)XML文件的解析與更新,需要的可以參考一下
    2022-03-03
  • rabbitmq basicReject/basicNack/basicRecover的區(qū)別及說明

    rabbitmq basicReject/basicNack/basicRecover的區(qū)別及說明

    這篇文章主要介紹了rabbitmq basicReject/basicNack/basicRecover的區(qū)別及說明,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Mybatis中SqlSession下的四大對象之執(zhí)行器(executor)

    Mybatis中SqlSession下的四大對象之執(zhí)行器(executor)

    mybatis中sqlsession下的四大對象是指:executor, statementHandler,parameterHandler,resultHandler對象。這篇文章主要介紹了Mybatis中SqlSession下的四大對象之執(zhí)行器(executor),需要的朋友可以參考下
    2019-04-04
  • java實(shí)現(xiàn)桌球游戲

    java實(shí)現(xiàn)桌球游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)桌球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Java中的三元運(yùn)算(三目運(yùn)算)以后用得到!

    Java中的三元運(yùn)算(三目運(yùn)算)以后用得到!

    Java提供了一個(gè)三元運(yùn)算符,可以同時(shí)操作3個(gè)表達(dá)式,下面這篇文章主要給大家介紹了關(guān)于Java中三元運(yùn)算(三目運(yùn)算)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • java如何消除太多的if else判斷示例代碼

    java如何消除太多的if else判斷示例代碼

    這篇文章主要介紹了java如何消除太多的if else判斷,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Java和Scala集合間的相互轉(zhuǎn)換方式

    Java和Scala集合間的相互轉(zhuǎn)換方式

    這篇文章主要介紹了Java和Scala集合間的相互轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java實(shí)現(xiàn)九宮格拼圖游戲

    java實(shí)現(xiàn)九宮格拼圖游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)九宮格拼圖游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評論