【SpringBoot】MD5加鹽算法的詳解

目錄

一、什么是加鹽算法

二、如何實現加鹽算法

2.1 加鹽算法代碼實現

2.2 注冊頁面中進行密碼加鹽

2.3 登錄頁面進行加鹽的解密

2.4 注冊和登錄


一、什么是加鹽算法

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

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

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

  1. 生成鹽值:后端在存儲一個密碼時,首先會隨機生成一個鹽值。這個鹽值是一個隨機字符串,用于增加密碼的復雜性。
  2. 結合鹽值和密碼:將生成的鹽值和用戶輸入的密碼進行有規則的結合,通常是將鹽值附加在密碼的前面或后面,或者通過其他方式進行組合。
  3. 加密處理:將結合后的數據使用加密算法進行加密。常見的加密算法包括MD5、SHA-256等。在Spring Security中,還可以使用更強大的加密方式,如BCrypt。本期講解使用MD5
  4. 存儲加密后的數據和鹽值:將加密后的數據和鹽值按照一定規則組合起來,并存儲在數據庫中。通常,鹽值會被保存在與加密密碼相同的記錄中,以便在驗證用戶密碼時使用。

二、如何實現加鹽算法

2.1 加鹽算法代碼實現

首先,我們要了解到:

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

生成一個 MD5 散列值,可使用 DigestUtils類 中的 .md5DigestAsHex 方法將生成的隨機鹽值 salt password 結合,并通過 .getBytes 將結合后的字符串轉換成一個字節數組即 .getBytes(StandardCharsets.UTF_8)

此外需要注意的是:

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

代碼實現:

/*** 加密工具類*/
public class PasswordUtils {public static String encrypt(String password){// 1.鹽值String salt = UUID.randomUUID().toString().replace("-","");// 2.將鹽值+密碼進行 md5 得到最終密碼String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));// 3.將鹽值和最終密碼返回return salt+"$"+finalPassword;}/*** 加鹽驗證* @param password 待驗證的密碼* @param dbPassword 數據庫中的密碼:鹽值$最終密碼* @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.加密待驗證的密碼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"));}
}

在該類中生成一個 main 方法,測試最后生成的字符串符不符合預期,輸出結果:

將上述的字符串,定義為一個字符串,驗證是否加密成功。?

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

?


2.2 注冊頁面中進行密碼加鹽

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

2.3 登錄頁面進行加鹽的解密

/*** 登錄* @param userinfoVO* @return*/@RequestMapping("/login")public ResultAjax login(UserinfoVO userinfoVO, HttpServletRequest request) {// 1.參數校驗if (userinfoVO == null || !StringUtils.hasLength(userinfoVO.getUsername())|| !StringUtils.hasLength(userinfoVO.getPassword())) {// 非法登錄return ResultAjax.fail(-1,"非法登錄!");}// 2.根據用戶名查詢對象,判斷用戶名是否錯誤Userinfo userinfo = userService.getUserByName(userinfoVO.getUsername());if (userinfo == null && userinfo.getId() == 0) {return ResultAjax.fail(-2,"賬號或密碼錯誤!");}// 3.使用對象中的密碼和輸入的密碼進行對比,判斷密碼是否錯誤// 加鹽解密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.結果返回給用戶return ResultAjax.success(1);}

?此時查詢數據庫中,只有一條數據,下面再注冊一個用戶,觀察是否生成密碼。


2.4 注冊和登錄

注冊頁面

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

在數據中查詢對應的數據,驗證密碼 123 被加秘為一大串字符串。

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

跳轉到個人頁面。

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


本篇博客到這里就結束了,感謝各位的觀看。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73317.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73317.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73317.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uniapp移動端圖片比較器組件,仿英偉達官網rtx光追圖片比較器功能

組件下載地址:https://ext.dcloud.net.cn/plugin?id22609 已測試h5和微信小程序,理論支持全平臺 亮點: 簡單易用 使用js計算而不是resize屬性,定制化程度更高 組件掛在后可播放指示線動畫,提示用戶可以拖拽比較圖片…

CI/CD—Jenkins實現自動構建Docker鏡像運行Java程序

實現原理 1、Java代碼中創建一個dockerfile文件 --> 2、代碼上傳至GitLab --> 3、Jenkins同步GitLab的代碼進行構建生成jar --> 4、Jenkins將jar包和dockerfile文件傳到測試服務器上 --> 5、在測試服務器上執行dockerfile構建jar鏡像 --> 6、鏡像構建完運行容器…

docker 搭建alpine下nginx1.26/mysql8.0/php7.4環境

docker 搭建alpine下nginx1.26/mysql8.0/php7.4環境 docker-compose.yml services:mysql-8.0:container_name: mysql-8.0image: mysql:8.0restart: always#ports:#- "3306:3306"volumes:- ./etc/mysql/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro- ./var/log…

隊列的簡單例題

題目如下 模擬隊列 首先你要明白隊列的話 只有隊尾才能進行新增,也就是入隊 只有隊首才能出隊,也就是刪除 隊首隊尾指針一開始默認都是0 相當于隊列中一開始是有一個元素的就是 0的位置 隊首指針head0 隊尾指針tail0 1.入隊也就是隊尾要先賦值&#xf…

vue3+elementuiplus的table表格動態高度

table表格流體高度 1、前提 了解自定義指令、hooks 2、核心思路 通過自定義指令(new ResizeObserver)監聽表格變化,然后通過hooks去更新表格高度。 3、核心代碼 src/directives/resize.ts // import { debounce } from /utils;import { t…

Apache POI詳解

目錄 前言 Apache POI是一個強大的Java庫,廣泛用于處理Microsoft Office文檔,包括Word、Excel和PowerPoint等。本文將詳細介紹如何使用Apache POI庫操作Word模板(包括替換占位符、操作表格)、將Word文檔轉換為PDF,以及…

AutoGen多角色、多用戶、多智能體對話系統

2023-03-11-AutoGen 使用【autoGenchainlitdeepSeek】實現【多角色、多用戶、多智能體對話系統】 1-核心思路 01)技術要點:autoGenchainlitdeepSeek02)什么是autoGen->autogen是微軟旗下的多智能體的框架03)什么是chainlit-&g…

問deepseek: OpenFOAM并行分區后,是如何實現ldumatrix矩陣向量乘法計算邏輯的?

在OpenFOAM中,lduMatrix 是用于存儲稀疏矩陣的類,支持并行計算。并行分區后,lduMatrix 的矩陣向量乘法通過以下步驟實現: 1. 矩陣分區 分區:將矩陣和向量分配到多個處理器上,每個處理器負責一部分。接口&…

數據類設計_圖片類設計之4_規則類圖形混合算法(前端架構)

前言 學的東西多了,要想辦法用出來.C和C是偏向底層的語言,直接與數據打交道.嘗試做一些和數據方面相關的內容 引入 接續上一篇,討論圖片類型設計出來后在場景中如何表達,以及圖片的混合算法.前面的內容屬于鋪墊和基礎,這篇內容和實際聯系起來了. 背景圖和前景圖 這里筆者想先…

【openwebui 搭建本地知識庫(RAG搭建本地知識庫)】

安裝準備 openwebui 這個本地安裝之前寫過使用python安裝。也可以直接用docker 命令 docker run --rm -d \-p 3080:8080 \-p 3081:8081 \-e WEBUI_AUTHtrue \-e DEFAULT_LOCALEcn \-e GLOBAL_LOG_LEVEL"INFO" \-e AIOHTTP_CLIENT_TIMEOUT100 \--privilegedtrue \-…

Nginx的流式響應配置詳解

現在大模型場景繁多,項目中涉及nginx轉發大模型的流式數據時,需配置nginx的轉發策略: location /streaming {proxy_pass http://backend_server;proxy_cache off; # 關閉緩存proxy_buffering off; # 關閉代理緩沖chunked_transfer_encoding …

git使用命令總結

文章目錄 Git 復制創建提交步驟Git 全局設置:創建 git 倉庫:已有倉庫? 遇到問題解決辦法:問題一先git pull一下,具體流程為以下幾步: 詳細步驟 Git 復制 git clone -b RobotModelSetting/develop https://gitlab.123/PROJECT/123.git創建提…

flutter 圖片資源路徑管理

1. 創建統一資源管理類 創建一個單獨的 Dart 文件(比如 manager.dart),將所有圖片路徑集中管理。這樣在引用圖片時,不需要每次都手動輸入完整路徑,只需通過常量引用即可。 //manager.dartclass Manager { static co…

Android Retrofit 框架配置與構建模塊深入源碼分析(六)

一、引言 Retrofit 是一個在 Android 和 Java 開發中廣泛使用的類型安全的 HTTP 客戶端。它通過簡潔的 API 設計,使得網絡請求的處理變得高效且易于管理。配置與構建模塊作為 Retrofit 的基礎部分,承擔著初始化和定制 Retrofit 實例的重要任務。開發者可…

80.Dictionary 字典 C#例子

使用 C# 中的 Dictionary 數據結構 在 C# 中&#xff0c;Dictionary<TKey, TValue> 是一個非常強大的數據結構&#xff0c;用于存儲鍵值對。它提供了高效的查找、插入和刪除操作&#xff0c;適用于需要快速訪問數據的場景。本文將通過一個簡單的示例&#xff0c;介紹如何…

tomcat負載均衡配置

這里拿Nginx和之前做的Tomcat 多實例來實現tomcat負載均衡 1.準備多實例與nginx tomcat單機多實例部署-CSDN博客 2.配置nginx做負載均衡 upstream tomcat{ server 192.168.60.11:8081; server 192.168.60.11:8082; server 192.168.60.11:8083; } ser…

C語言中scanf(“%c“,s)會出現的問題

scanf("%c%c", &word[0], &word[1]);的行為與輸入緩沖區的內容密切相關。你提到輸入ab后&#xff0c;word[0]是\n&#xff0c;這通常是因為輸入緩沖區中殘留了換行符&#xff08;\n&#xff09;。 一、原因分析 換行符殘留 若在輸入ab之前有其他輸入操作&a…

SealOS部署k8s集群(單節點)

一、 先決條件 每個集群節點應該有不同的主機名。需要在 K8s 集群的第一個 master 節點上運行 sealos run 命令。建議使用干凈的操作系統來創建集群。不要自己裝 Docker&#xff01;支持大多數 Linux發行版&#xff0c;但內核版本建議5以上。例如&#xff1a;Ubuntu、CentOS、…

Linux 服務器安全配置:密碼復雜度與登錄超時設置

Linux服務器安全配置指南:密碼復雜度與登錄超時設置 一、密碼復雜度設置 通過PAM模塊pam_cracklib.so實現密碼強度策略,配置文件: system-auth該文件主要用于定義系統范圍內的認證策略,涵蓋了用戶登錄、su 命令切換用戶、sudo 權限提升等多種認證場景。當用戶嘗試進行系…

AI Agent開發框架分析:前端視角

1. Mastra (https://mastra.ai/docs) 優點&#xff1a; 提供直觀的界面構建器&#xff0c;適合無代碼/低代碼開發支持JavaScript/TypeScript&#xff0c;可直接集成到前端項目可視化工作流設計&#xff0c;降低入門門檻內置多種UI組件&#xff0c;加速前端開發 缺點&#xf…