PBKDF2全面指南(SpringBoot實現版)

文章目錄

    • 第一部分:PBKDF2基礎概念
      • 1. 什么是PBKDF2?
      • 2. 為什么需要PBKDF2?
      • 3. PBKDF2的工作原理
      • 4. PBKDF2與其他密碼散列函數的比較
    • 第二部分:在Java和SpringBoot中使用PBKDF2
      • 1. Java內置的PBKDF2支持
      • 2. SpringBoot中集成PBKDF2
        • 2.1 添加依賴
        • 2.2 配置PBKDF2密碼編碼器
        • 2.3 自定義PBKDF2編碼器參數
        • 2.4 在用戶服務中使用PBKDF2編碼器
    • 第三部分:PBKDF2實戰 - 完整SpringBoot應用示例
      • 1. 項目結構
      • 2. Maven依賴
      • 3. 應用屬性配置
      • 4. 用戶模型
      • 5. 用戶存儲庫
      • 6. 安全配置
      • 7. 用戶詳情服務
      • 8. 用戶服務
      • 9. 控制器
      • 10. 模板頁面
      • 11. 應用主類
    • 第四部分:PBKDF2性能和安全性分析
      • 1. 如何選擇適當的迭代次數
      • 2. 鹽值長度選擇
      • 3. PBKDF2與Bcrypt/Argon2的比較
    • 第五部分:PBKDF2最佳實踐和常見錯誤
      • 1. PBKDF2安全最佳實踐
      • 2. 常見錯誤
        • 錯誤1:使用固定或可預測的鹽值
        • 錯誤2:迭代次數過低
        • 錯誤3:在客戶端進行密碼散列
        • 錯誤4:忽略密碼長度限制
        • 錯誤5:不正確地比較散列值
      • 3. 在生產環境中的注意事項
    • 第六部分:總結
      • 1. PBKDF2要點總結
        • 錯誤3:在客戶端進行密碼散列
        • 錯誤4:忽略密碼長度限制
        • 錯誤5:不正確地比較散列值
      • 3. 在生產環境中的注意事項
    • 第六部分:總結
      • 1. PBKDF2要點總結

第一部分:PBKDF2基礎概念

1. 什么是PBKDF2?

PBKDF2(Password-Based Key Derivation Function 2)是一種密鑰派生函數,由RSA實驗室的RSA公共密鑰加密標準(PKCS)系列中的第5號文檔《基于密碼的加密標準》(PKCS#5 v2.0)定義,并已成為Internet工程任務組(IETF)的RFC 2898標準。

簡單來說,PBKDF2是一種用于將用戶密碼安全地轉換為加密密鑰或散列值的算法,它專門設計用來抵抗暴力破解和字典攻擊。

2. 為什么需要PBKDF2?

在現代應用程序中,我們不應該以明文形式存儲用戶密碼,而應該存儲密碼的散列值。傳統的散列函數(如MD5或SHA-1)存在一些問題:

  1. 速度太快:現代硬件可以快速計算這些散列值,使暴力破解成為可能
  2. 缺乏鹽值(salt):相同的輸入總是產生相同的輸出,這使預計算攻擊(彩虹表)成為可能
  3. 并行計算:攻擊者可以使用GPU并行計算多個散列值

PBKDF2解決了這些問題:

  • 它引入了計算成本因子(迭代次數),使計算過程變慢
  • 它使用隨機鹽值,確保即使相同的密碼也會生成不同的散列值
  • 它是順序計算的,難以并行化,這降低了GPU加速攻擊的效率

3. PBKDF2的工作原理

詳細步驟解析:

  1. 輸入收集:獲取用戶密碼和隨機生成的鹽值
  2. 偽隨機函數選擇:通常使用HMAC-SHA1、HMAC-SHA256或HMAC-SHA512
  3. 應用PBKDF2函數
    • 將密碼和鹽值作為輸入
    • 指定迭代次數(通常為至少10,000次,現代系統建議100,000次以上)
    • 指定所需的輸出長度(通常為256位或512位)
  4. 輸出:生成最終的密鑰或散列值

數學上,PBKDF2可表示為:

DK = PBKDF2(PRF, Password, Salt, c, dkLen)

其中:

  • DK:派生密鑰
  • PRF:偽隨機函數(如HMAC-SHA256)
  • Password:用戶密碼
  • Salt:隨機鹽值
  • c:迭代次數
  • dkLen:派生密鑰的長度

4. PBKDF2與其他密碼散列函數的比較

函數優點缺點安全性
MD5/SHA速度快無鹽值,計算成本低極低
PBKDF2有鹽值,可調整迭代次數可以GPU并行化(相對Bcrypt和Argon2而言)中高
Bcrypt有鹽值,內置成本因子,抗GPU攻擊內存需求固定,輸出長度固定為192位
Argon2可調整時間、內存、并行度,2015年密碼散列競賽冠軍相對較新,庫支持不如PBKDF2廣泛非常高

何時選擇PBKDF2

  • 當你需要一個廣泛支持、經過時間考驗的算法
  • 當你需要符合某些特定標準(如FIPS)
  • 當你需要生成特定長度的密鑰而不僅僅是密碼散列

第二部分:在Java和SpringBoot中使用PBKDF2

1. Java內置的PBKDF2支持

從Java 8開始,JDK提供了內置的PBKDF2實現,位于javax.crypto包中:

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;public class PBKDF2Hasher {// 算法名稱private static final String ALGORITHM = "PBKDF2WithHmacSHA256";// 迭代次數private static final int ITERATIONS = 65536;// 密鑰長度private static final int KEY_LENGTH = 256;// 鹽值長度private static final int SALT_LENGTH = 16;// 生成鹽值public static byte[] generateSalt() {SecureRandom random = new SecureRandom();byte[] salt = new byte[SALT_LENGTH];random.nextBytes(salt);return salt;}// 使用PBKDF2生成散列值public static byte[] hash(char[] password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH);SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);return factory.generateSecret(spec).getEncoded();}// 驗證密碼public static boolean verify(char[] password, byte[] hash, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {byte[] testHash = hash(password, salt);return Arrays.equals(hash, testHash);}// 生成散列值和鹽值,并編碼為Base64字符串public static String[] hashPassword(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {byte[] salt = generateSalt();byte[] hash = hash(password.toCharArray(), salt);String hashString = Base64.getEncoder().encodeToString(hash);String saltString = Base64.getEncoder().encodeToString(salt);return new String[] { hashString, saltString };}// 從Base64字符串中驗證密碼public static boolean verifyPassword(String password, String hashString, String saltString) throws NoSuchAlgorithmException, InvalidKeySpecException {byte[] hash = Base64.getDecoder().decode(hashString);byte[] salt = Base64.getDecoder().decode(saltString);return verify(password.toCharArray(), hash, salt);}
} 

2. SpringBoot中集成PBKDF2

在Spring Security中,從5.0版本開始,提供了內置的PBKDF2密碼編碼器Pbkdf2PasswordEncoder。以下是在SpringBoot項目中集成PBKDF2的方法:

2.1 添加依賴

首先,確保你的SpringBoot項目中包含Spring Security依賴:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.2 配置PBKDF2密碼編碼器

在Spring Security配置類中配置Pbkdf2PasswordEncoder

package com.example.pbkdf2demo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();return http.build();}@Beanpublic PasswordEncoder passwordEncoder() {// 創建PBKDF2密碼編碼器// 參數分別是:密鑰迭代次數、密鑰長度(比特)// Spring Security 5.x 版本return new Pbkdf2PasswordEncoder("", 185000, 256);// Spring Security 6.x 及更高版本// return Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8();}
}
2.3 自定義PBKDF2編碼器參數

如果需要更精細地控制PBKDF2參數,可以這樣配置:

@Bean
public PasswordEncoder passwordEncoder() {// SpringBoot 2.x 和 Spring Security 5.xString secret = "your-secret"; // 可選的密鑰int iterations = 210000; // 迭代次數int hashWidth = 512; // 哈希長度(比特)return new Pbkdf2PasswordEncoder(secret,iterations,hashWidth);// SpringBoot 3.x 和 Spring Security 6.x/*return Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8().secret("your-secret").iterations(210000).hashWidth(512).algorithm(Pbkdf2PasswordEncoder.SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA512).build();*/
}
2.4 在用戶服務中使用PBKDF2編碼器
package com.example.pbkdf2demo.service;import com.example.pbkdf2demo.model.User;
import com.example.pbkdf2demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Autowiredprivate PasswordEncoder passwordEncoder;public User registerUser(String username, String password) {// 判斷用戶名是否已存在if (userRepository.findByUsername(username).isPresent()) {throw new IllegalArgumentException("用戶名已存在");}// 使用PBKDF2編碼密碼String encodedPassword = passwordEncoder.encode(password);// 創建新用戶User user = new User();user.setUsername(username);user.setPassword(encodedPassword); // 存儲PBKDF2編碼后的密碼user.setEnabled(true);return userRepository.save(user);}public boolean authenticate(String username, String password) {return userRepository.findByUsername(username).map(user -> passwordEncoder.matches(password, user.getPassword())

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

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

相關文章

RTP Payload Format for H.264 Vide(1)

摘要&#xff1a;&#xff1a; 本備忘錄描述了一種用于 ITU-T H.264 視頻編碼標準&#xff08;與 ISO/IEC 國際標準 14496-10 技術上相同&#xff09;的 RTP 負載格式&#xff0c;但不包括可伸縮視頻編碼&#xff08;SVC&#xff09;擴展和多視角視頻編碼&#xff08;MVC&#…

論文翻譯:2024-arxiv How to Steer LLM Latents for Hallucination Detection?

總目錄 大模型安全相關研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 How to Steer LLM Latents for Hallucination Detection? https://arxiv.org/pdf/2503.01917 https://www.doubao.com/chat/2818934852496130 其它資料: https://blog.csdn.net/we…

第四篇:[特殊字符] 深入理解MyBatis[特殊字符] 掌握MyBatis Generator ——入門與實戰

引言 什么是 MyBatis Generator&#xff1f; MyBatis Generator (MBG) 是一個代碼生成工具&#xff0c;專為 MyBatis 框架設計。它可以根據數據庫表結構自動生成 Java 實體類、Mapper 接口、Mapper XML 文件以及 Example 類。通過使用 MBG&#xff0c;開發者可以顯著減少編寫…

利用純JS開發瀏覽器小窗口移動廣告小功能

效果展示 直接上代碼 如果要用到vue項目里面&#xff0c;直接按照vue的寫法改動就行&#xff0c;一般沒有多大的問題&#xff0c;頂部的占位是我項目需求&#xff0c;你可以按照要求改動。 <!DOCTYPE html> <html> <head><meta charset"utf-8"…

React 更新 state 中的數組

更新 state 中的數組 數組是另外一種可以存儲在 state 中的 JavaScript 對象&#xff0c;它雖然是可變的&#xff0c;但是卻應該被視為不可變。同對象一樣&#xff0c;當你想要更新存儲于 state 中的數組時&#xff0c;你需要創建一個新的數組&#xff08;或者創建一份已有數組…

java -jar與java -cp的區別

java -jar與java -cp 1、情景描述2、情景分析3、兩者區別 通常情況下&#xff0c;我們會看到以下兩種命令啟動的Java程序&#xff1a; java -jar xxx.jar [args] java -cp xxx.jar mainclass [args]這兩種用法有什么區別呢&#xff1f; 1、情景描述 1&#xff09;Java打包單個…

【Java】面向對象程序三板斧——如何優雅設計包、封裝數據與優化代碼塊?

&#x1f381;個人主頁&#xff1a;User_芊芊君子 &#x1f389;歡迎大家點贊&#x1f44d;評論&#x1f4dd;收藏?文章 &#x1f50d;系列專欄&#xff1a;【Java】內容概括 【前言】 在Java編程中&#xff0c;類和對象是面向對象編程的核心概念。而包&#xff08;Package&am…

玩轉Docker | 使用Docker搭建Blog微博系統

玩轉Docker | 使用Docker搭建Blog微博系統 前言一、Blog介紹項目簡介主要特點二、系統要求環境要求環境檢查Docker版本檢查檢查操作系統版本三、部署Blog服務下載鏡像創建容器檢查容器狀態設置權限檢查服務端口安全設置四、訪問Blog系統訪問Blog首頁登錄Blog五、總結前言 在數字…

用Java NIO模擬HTTPS

HTTPS流程 名詞解釋&#xff1a; R1:隨機數1 R2:隨機數2 R3:隨機數3 publicKey:公鑰 privateKey:私鑰 要提供https服務&#xff0c;服務端需要安裝數字證書&#xff0c;在&#xff08;TCP建立連接之后&#xff09;TLS握手時發給客戶端&#xff0c;客戶端驗證證書&#x…

樹莓派_利用Ubuntu搭建gitlab

樹莓派_利用Ubuntu搭建gitlab 一、給樹莓派3A搭建基本系統 1、下載系統鏡像 https://cdimage.ubuntu.com/ubuntu/releases/18.04/release/ 2、準備系統SD卡 二、給樹莓派設備聯網 1、串口后臺登錄 使用串口登錄后臺是最便捷的&#xff0c;因為前期網絡可能不好直接成功 默…

Hook_Unfinished

#include <windows.h>// 假設這兩個函數是存在的 void DoRD() {} void 改堆棧cal1() {} void 改回堆棧cal1() {}__declspec(naked) void HOOKcall() {__asm{pushadnop}__asm{popadmov eax, dword ptr [esi 8]sub eax, ecxretn} }int main() {// 第一個 Hook 操作DWORD H…

數據結構(六)——紅黑樹及模擬實現

目錄 前言 紅黑樹的概念及性質 紅黑樹的效率 紅黑樹的結構 紅黑樹的插入 變色不旋轉 單旋變色 雙旋變色 插入代碼如下所示&#xff1a; 紅黑樹的查找 紅黑樹的驗證 紅黑樹代碼如下所示&#xff1a; 小結 前言 在前面的文章我們介紹了AVL這一棵完全二叉搜索樹&…

c# 數據結構 鏈表篇 有關雙向鏈表的一切

本人能力有限,如有不足還請斧正 目錄 0.雙向鏈表的好處 1.雙向鏈表的分類 2.不帶頭節點的標準雙向鏈表 節點類:有頭有尾 鏈表類:也可以有頭有尾 也可以只有頭 增 頭插 尾插 刪 查 改 遍歷 全部代碼 3.循環雙向鏈表 節點類 鏈表類 增 頭插 尾插 刪 查 遍歷…

Numba 從零基礎到實戰:解鎖 Python 性能新境界

Numba 從零基礎到實戰&#xff1a;解鎖 Python 性能新境界 一、引言 在 Python 的世界里&#xff0c;性能一直是一個備受關注的話題。Python 以其簡潔易讀的語法和豐富的庫生態&#xff0c;深受開發者喜愛&#xff0c;但在處理一些計算密集型任務時&#xff0c;其執行速度往往…

單位門戶網站被攻擊后的安全防護策略

政府網站安全現狀與挑戰 近年來&#xff0c;隨著數字化進程的加速&#xff0c;政府門戶網站已成為政務公開和服務公眾的重要窗口。然而&#xff0c;網絡安全形勢卻日益嚴峻。國家互聯網應急中心的數據顯示&#xff0c;政府網站已成為黑客攻擊的重點目標&#xff0c;被篡改和被…

Spring Boot 項目三種打印日志的方法詳解。Logger,log,logger 解讀。

目錄 一. 打印日志的常見三種方法&#xff1f; 1.1 手動創建 Logger 對象&#xff08;基于SLF4J API&#xff09; 1.2 使用 Lombok 插件的 Slf4j 注解 1.3 使用 Spring 的 Log 接口&#xff08;使用頻率較低&#xff09; 二. 常見的 Logger&#xff0c;logger&#xff0c;…

NI的LABVIEW工具安裝及卸載步驟說明

一.介紹 最近接到個轉交的項目&#xff0c;項目主要作為上位機工具開發&#xff0c;在對接下位機時&#xff0c;有用到NI的labview工具。labview軟件是由美國國家儀器&#xff08;NI&#xff09;公司研制開發的一種程序開發環境&#xff0c;主要用于汽車測試、數據采集、芯片測…

cmd 終端輸出亂碼問題 |Visual Studio 控制臺輸出中文亂碼解決

在網上下載&#xff0c;或者移植別人的代碼到自己的電腦&#xff0c;使用VS運行后&#xff0c;控制臺輸出中文可能出現亂碼。這是因為源代碼的編碼格式和控制臺的編碼格式不一致。 文章目錄 查看源代碼文件編碼格式查看輸出控制臺編碼格式修改編碼格式修改終端代碼頁 補充總結 …

A009-基于pytest的網易云自動化測試

題 目 :基于pytest的網易云自動化測試 主要內容 綜合應用所學的軟件測試理論和方法,實現網易云的功能自動化測試。 (1)自動化測試介紹; (2)自動化功能測試框架介紹; (3)設計功能測試用例 (4)書寫自動化測試腳本; (5)測試評價與結論。 任務要求 (1)能…

LVGL Video控件和Radiobtn控件詳解

LVGL Video控件和Radiobtn控件詳解 一、 Video控件詳解1. 概述2. 創建和初始化3. 基本屬性設置4. 視頻控制5. 回調函數6. 高級功能7. 注意事項 二、Radiobtn控件詳解1. 概述2. 創建和初始化3. 屬性設置4. 狀態控制5. 組管理6. 事件處理7. 樣式設置8. 注意事項 三、效果展示四、…