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.mzph.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. 注意事项 三、效果展示四、…