Spring Boot 密码加密的 2 种姿势!

加密Spring Boot项目中配置文件的明文密码 文章目录加密Spring Boot项目中配置文件的明文密码添加依赖和插件使用jasypt加密过程小结参考文档 加密Spring Boot项目中配置文件的明文密码 如果不想在Spring Boot项目配置文件存储明文密码(比如MySQL密码、Redis密码等),一种简单的方法的方法是运行Spring Boot应用时以注入环境变量的方式来注入密码,另外一种就是在配置文件中加密存储明文密码。 本文讲解了... 阅读详情

先说一句:密码是无法解密的。

密码无法解密,还是为了确保系统安全。今天松就来和大家聊一聊,密码要如何处理,才能在最大程度上确保我们的系统安全。

1.为什么要加密

2011 年 12 月 21 日,有人在网络上公开了一个包含 600 万个某网站用户资料的数据库,数据全部为明文储存,包含用户名、密码以及注册邮箱。事件发生后该网站在微博、官方网站等渠道发出了声明,解释说此数据库系 2009 年备份所用,因不明原因泄露,已经向警方报案,后又在官网发出了公开道歉信。

在接下来的十多天里,金山、网易、京东、当当、新浪等多家公司被卷入到这次事件中。整个事件中最触目惊心的莫过于 该网站 把用户密码明文存储,由于很多用户是多个网站共用一个密码,因此一个网站密码泄露就会造成很大的安全隐患。由于有了这么多前车之鉴,我们现在做系统时,密码都要加密处理。

这次泄密,也留下了一些有趣的事情,特别是对于广大程序员设置密码这一项。人们从 该网站泄密的文件中,发现了一些好玩的密码,例如如下这些:

  • ppnn13%dkstFeb.1st 这段密码的中文解析是:娉娉袅袅十三余,豆蔻梢头二月初。

  • csbt34.ydhl12s 这段密码的中文解析是:池上碧苔三四点,叶底黄鹂一两声

  • ...

等等不一而足,你会发现很多程序员的人文素养还是非常高的,让人啧啧称奇。

2.加密方案

密码加密我们一般会用到散列函数,又称散列算法、哈希函数,这是一种从任何数据中创建数字“指纹”的方法。

散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来,然后将数据打乱混合,重新创建一个散列值。散列值通常用一个短的随机字母和数字组成的字符串来代表。好的散列函数在输入域中很少出现散列冲突。在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到。

我们常用的散列函数有 MD5 消息摘要算法、安全散列算法(Secure Hash Algorithm)。

但是仅仅使用散列函数还不够,单纯的只使用散列函数,如果两个用户密码明文相同,生成的密文也会相同,这样就增加的密码泄漏的风险。

为了增加密码的安全性,一般在密码加密过程中还需要加盐,所谓的盐可以是一个随机数也可以是用户名,加盐之后,即使密码明文相同的用户生成的密码密文也不相同,这可以极大的提高密码的安全性。

传统的加盐方式需要在数据库中有专门的字段来记录盐值,这个字段可能是用户名字段(因为用户名唯一),也可能是一个专门记录盐值的字段,这样的配置比较繁琐。

Spring Security 提供了多种密码加密方案,官方推荐使用 BCryptPasswordEncoder,BCryptPasswordEncoder 使用 BCrypt 强哈希函数,开发者在使用时可以选择提供 strength 和 SecureRandom 实例。strength 越大,密钥的迭代次数越多,密钥迭代次数为 2^strength。strength 取值在 4~31 之间,默认为 10。

不同于 Shiro 中需要自己处理密码加盐,在 Spring Security 中,BCryptPasswordEncoder 就自带了盐,处理起来非常方便。

3.实践

3.1 codec 加密

commons-codec 是一个 Apache 上的开源项目,用它可以方便的实现密码加密。松哥的V 部落项目中就是采用的这种方案(https://github.com/lenve/VBlog)。在 Spring Security 还未推出 BCryptPasswordEncoder 的时候,commons-codec 还是一个比较常见的解决方案。

所以,这里我先来给大家介绍下 commons-codec 的用法。

首先我们需要引入 commons-codec 的依赖:

<dependency>
 <groupId>commons-codec</groupId>
 <artifactId>commons-codec</artifactId>
 <version>1.11</version>
</dependency>

然后自定义一个 PasswordEncoder:

@Component
public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence rawPassword) {
        return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes());
    }

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return encodedPassword.equals(DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes()));
    }
}

在 Spring Security 中,PasswordEncoder 专门用来处理密码的加密与比对工作,我们自定义 MyPasswordEncoder 并实现 PasswordEncoder 接口,还需要实现该接口中的两个方法:

  1. encode 方法表示对密码进行加密,参数 rawPassword 就是你传入的明文密码,返回的则是加密之后的密文,这里的加密方案采用了 MD5。

  2. matches 方法表示对密码进行比对,参数 rawPassword 相当于是用户登录时传入的密码,encodedPassword 则相当于是加密后的密码(从数据库中查询而来)。

最后记得将 MyPasswordEncoder 通过 @Component 注解标记为 Spring 容器中的一个组件。

这样用户在登录时,就会自动调用 matches 方法进行密码比对。

当然,使用了 MyPasswordEncoder 之后,在用户注册时,就需要将密码加密之后存入数据库中,方式如下:

public int reg(User user) {
    ...
    //插入用户,插入之前先对密码进行加密
    user.setPassword(passwordEncoder.encode(user.getPassword()));
    result = userMapper.reg(user);
    ...
}

其实很简单,就是调用 encode 方法对密码进行加密。完整代码大家可以参考 V 部落(https://github.com/lenve/VBlog),我这里就不赘述了。

3.2 BCryptPasswordEncoder 加密

但是自己定义 PasswordEncoder 还是有些麻烦,特别是处理密码加盐问题的时候。

所以在 Spring Security 中提供了 BCryptPasswordEncoder,使得密码加密加盐变得非常容易。只需要提供 BCryptPasswordEncoder 这个 Bean 的实例即可,微人事就是采用了这种方案(https://github.com/lenve/vhr),如下:

@Bean
PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(10);
}

创建 BCryptPasswordEncoder 时传入的参数 10 就是 strength,即密钥的迭代次数(也可以不配置,默认为 10)。同时,配置的内存用户的密码也不再是 123 了,如下:

auth.inMemoryAuthentication()
.withUser("admin")
.password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq")
.roles("ADMIN", "USER")
.and()
.withUser("sang")
.password("$2a$10$eUHbAOMq4bpxTvOVz33LIehLe3fu6NwqC9tdOcxJXEhyZ4simqXTC")
.roles("USER");

这里的密码就是使用 BCryptPasswordEncoder 加密后的密码,虽然 admin 和 sang 加密后的密码不一样,但是明文都是 123。配置完成后,使用 admin/123 或者 sang/123 就可以实现登录。

本案例使用了配置在内存中的用户,一般情况下,用户信息是存储在数据库中的,因此需要在用户注册时对密码进行加密处理,如下:

@Service
public class RegService {
    public int reg(String username, String password) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
        String encodePasswod = encoder.encode(password);
        return saveToDb(username, encodePasswod);
    }
}

用户将密码从前端传来之后,通过调用 BCryptPasswordEncoder 实例中的 encode 方法对密码进行加密处理,加密完成后将密文存入数据库。

4.源码浅析

最后我们再来稍微看一下 PasswordEncoder。

PasswordEncoder 是一个接口,里边只有三个方法:

public interface PasswordEncoder {
 String encode(CharSequence rawPassword);
 boolean matches(CharSequence rawPassword, String encodedPassword);
 default boolean upgradeEncoding(String encodedPassword) {
  return false;
 }
}

  • encode 方法用来对密码进行加密。

  • matches 方法用来对密码进行比对。

  • upgradeEncoding 表示是否需要对密码进行再次加密以使得密码更加安全,默认为 false。

Spring Security 为 PasswordEncoder 提供了很多实现:

但是老实说,自从有了 BCryptPasswordEncoder,我们很少关注其他实现类了。

PasswordEncoder 中的 encode 方法,是我们在用户注册的时候手动调用。

matches 方法,则是由系统调用,默认是在 DaoAuthenticationProvider#additionalAuthenticationChecks 方法中调用的。

protected void additionalAuthenticationChecks(UserDetails userDetails,
  UsernamePasswordAuthenticationToken authentication)
  throws AuthenticationException {
 if (authentication.getCredentials() == null) {
  logger.debug("Authentication failed: no credentials provided");
  throw new BadCredentialsException(messages.getMessage(
    "AbstractUserDetailsAuthenticationProvider.badCredentials",
    "Bad credentials"));
 }
 String presentedPassword = authentication.getCredentials().toString();
 if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
  logger.debug("Authentication failed: password does not match stored value");
  throw new BadCredentialsException(messages.getMessage(
    "AbstractUserDetailsAuthenticationProvider.badCredentials",
    "Bad credentials"));
 }
}

可以看到,密码比对就是通过 passwordEncoder.matches 方法来进行的。

ArcGIS中地理坐标系与投影坐标系以及投影转换 简单介绍arcgis软件中坐标系定义、设置和常见问题。 阅读详情

相关推荐

SAP MM采购合同创建全解析:ME31K操作与后台逻辑

在SAP ERP的物料管理模块中,采购合同作为框架协议的核心,定义了企业与供应商之间的长期供货关系。它与采购订单不同,合同不直接产生收货或发票,而是为后续采购订单提供数据源。创建合同(事务码ME31K)时,需要区分数量合同与金额合同,并维护抬头、行项目、有效期、价格条件和税码等关键信息。SAP通过源确定机制在创建采购订单时自动匹配合同,同时审批策略、编码范围和输出类型也会影响合同的实际可用性。掌握合同创建逻辑,能有效解决采购订单无法带出合同、审批未触发、价格缺失等高频问题。从ME31K实操出发,系统梳理采购

weixin_30000735的博客 196

SpringBootSecurity(用户密码加密&加密后用户的校验)

SpringBootSecurity(用户密码加密&加密后用户的校验)

weixin_46588020的博客 2124

autoware 激光-相机联合标定

autoware进行激光-相机联合标定 ~~~ 刚开始进行激光-相机联合标定的时候,出现了不少问题,在此记录一下整体标定流程,以防忘记。在此,特别感谢佳明师弟,在录制数据集时提供的帮助。 ~~~ 0.系统配置: Ubuntu18.04系统 ROS Melodic opencv 3.2.0 vlp-16 一.安装autoware 这部分网上教程挺多的,但我在编译的过程中仍存在不少bug,唉~_~。 二.安装calibration_camera_lidar,从a...

nuo112的博客 1万+

使用Encode加密和解密

使用Encode加密和解密

catcatchmouse的专栏 2673

【Ragflow】9.问答为什么比搜索响应慢?从源码角度深入分析

前几天看到有群友提到一个现象:Ragflow的搜索界面的问答速度很快,但聊天界面的问答速度很慢,究竟是什么原因?在深入挖掘源码之后,逐渐发现了问题的答案。

兴趣使然的创作者 2900

【物联网】基于LORA组网的远程环境监测系统设计(ThingsCloud云平台版)_资料编号34

实现一主多从的LORA组网远程通信,主机和两个从机都配备了STM32F103单片机与 LoRa 模块,主机作为中心设备及WIFI网关,负责接收和发送数据到远程物联网平台和手机APP,两个从机则负责采集数据并通过各自的 LoRa组网将数据发送给主机。

嵌入式阿齐Archie 1万+

使用encode对用户密码进行加密以及判断密码是否正确

BCryptPasswordEncoder提供了 encoder.matches()方法对原密码及加密后密码进行检验,若两者能对应上,返回true。当用户进行登录或注册的过程中输入密码时,密码通常以明文的方式传输到服务器进行校验。如果这时密码被非法手段获取,则会造成不可估量的损失。所以在开发过程中对重要信息进行加密处理非常有必要,例如用户密码。而且使用BCryptPasswordEncoder进行加密,其加密方式为动态加密,对相同的密码加密后的内容均不一样,所以无需担心不同用户使用相同密码从而造成混乱。

weixin_51496936的博客 821

基于 Spring Cloud 环境污染物数据分析与预测平台

基于 Spring Cloud 环境污染物数据分析与预测平台

934

SpringBoot集成Druid和数据库密码加密

SpringBoot集成Druid和数据库密码加密

m0_65014849的博客 3181

Python爬虫实战:使用Scrapy+Playwright高效爬取全球石油价格历史数据

python复制下载# 产品信息# 日期信息# 价格数据price = scrapy.Field() # 收盘价open = scrapy.Field() # 开盘价high = scrapy.Field() # 最高价low = scrapy.Field() # 最低价volume = scrapy.Field() # 交易量change_percent = scrapy.Field() # 涨跌幅# 元数据。

2201_76125261的博客 1020

杰理JL701N V142的SDK实现双备份自定义OTA教程和代码分享

摘要 本文档详细介绍了基于JL701N SDK的UART OTA升级功能开发方案。该方案采用双备份(Dual Bank)机制,通过串口实现安全可靠的固件远程更新。核心特性包括:1) 双备份升级机制确保升级失败可回滚;2) CRC-16/XMODEM校验保障数据完整性;3) 灵活的传输控制,支持自定义波特率和数据包大小。文档提供了完整的系统架构、API接口说明、通信协议规范以及移植指南,适用于生产烧录、现场升级等多种场景。配套Python升级工具简化了升级流程,使开发人员能够快速实现固件更新功能。

qq_42014563的博客 275

SpringBoot学习笔记之使用Druid为数据库密码加密

之前在项目的配置文件中看到关于数据库的配置,总觉得将数据库用户名和密码赤裸裸的展现他人面前非常不好。但是技术有限,见识有限,不知道该如何处理。同时所看到的项目都是这个样子的,所以觉得就这个样子吧。在集成Druid数据库连接池时,在官网文档中偶然发现可以在 SpringBoot 项目的配置文件中给数据库密码加密,正合心意。这次就记录一下整个实现过程。整个流程实践下来还是很简单的。就两个步骤:密码加密和配置参数。

蜗牛老师,专注编程领域 4943

【YOLOv11多模态融合改进】| CVPR2025 LCA轻量交叉注意力 双向模态交叉引导 + 双支路噪点抑制,兼顾纹理与热目标特征融合

可见光模态富含纹理、色彩、边缘细节,但夜间/低照度场景信噪比极低,暗区噪声泛滥;红外模态依靠热辐射凸显弱小目标、暗区物体轮廓,但缺失真实色彩与精细纹理。简单拼接/逐加融合仅做浅层特征叠加,无法建立可见光纹理、红外热特征的双向引导关联,两类模态互补信息无法精准互通;普通自注意力仅单模态内部建模,跨模态交互匮乏,红外热目标易被可见光暗噪声淹没,可见光有效纹理易被红外灰度信息覆盖;

Limiiiing的博客 115

Spring Boot 中密码加密的两种姿势!

先说一句:密码是无法解密的。大家也不要再问松哥微人事项目中的密码怎么解密了! 密码无法解密,还是为了确保系统安全。今天松哥就来和大家聊一聊,密码要如何处理,才能在最大程度上确保我们的系统安全。 本文是 Spring Security 系列的第 20 篇,阅读本系列前面的文章有助于更好的理解本文: 挖一个大坑,Spring Security 开搞! 松哥手把手带你入门 Spring Security,别再问密码怎么解密了 手把手教你定制 Spring Security 中的表单登录 Spring Secur

江南一点雨的专栏 1万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Spring Boot教程之四十:使用 Jasypt 加密 Spring Boot 项目中的密码

等数据库,并将数据库连接的真实密码存储在 Spring Boot 项目的配置文件(application.yml 或 application.properties)中。它将帮助您以极少的努力为您的项目添加基本的加密功能,并且无需编写任何代码,只需在您的项目中进行一些添加即可。Springboot 是一个非常强大的框架,它将帮助您添加加密功能而无需实现任何加密方法。:虽然 3.1 和 3.2 中的加密值(即加密字符串和输出)不同,但由于密钥相同,因此两种情况下解密都会产生相同的值(abcd1234)。

潜洋的专栏 2038

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Spring Boot密码加密

Spring Boot密码加密是一个涉及多个步骤的过程,包括引入加密依赖、配置加密工具、生成加密密钥和加密密码、配置解密以及在配置文件中使用加密后的密码等。通过遵循这些步骤,你可以有效地保护Spring Boot应用程序中的敏感信息,提高应用程序的安全性。同时,也需要注意安全存储加密密钥、定期更换加密密钥、备份加密信息以及测试加密解密功能等安全措施。

m0_70066267的博客 2393

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

告别明文密码!Spring Boot 的 BcryptPasswordEncoder 实战指南

是 Spring Security 提供的一个密码加密工具,它使用Bcrypt算法来加密密码。Bcrypt 是一种专门为密码存储设计的哈希算法,它的特点是慢哈希,即计算哈希值的过程比较慢,这样可以有效防止暴力破解。为什么需要它?直接存储用户的明文密码是非常危险的!如果数据库被泄露,攻击者可以直接获取用户的密码。使用加密后,即使数据库泄露,攻击者也无法轻易破解密码。🔒在 Spring Boot 中,是一个非常重要的工具,它通过 Bcrypt 算法确保密码的安全性。

qq_56158663的博客 2958

在Spring Boot项目中,对密码进行加密

Spring Boot密码加密是一个涉及多个步骤的过程,包括引入加密依赖、配置加密工具、生成加密密钥和加密密码、配置解密以及在配置文件中使用加密后的密码等。通过遵循这些步骤,你可以有效地保护Spring Boot应用程序中的敏感信息,提高应用程序的安全性。同时,也需要注意安全存储加密密钥、定期更换加密密钥、备份加密信息以及测试加密解密功能等安全措施。

陈辰学长的博客 1748

Spring Boot密码加密实战:从BCrypt到安全加固全解析

密码安全是现代Web应用开发的基石,其核心在于通过单向哈希函数对用户密码进行不可逆转换,确保即使数据库泄露,攻击者也无法轻易还原原始密码。这一原理通过自适应慢哈希算法实现,如BCrypt、PBKDF2等,它们通过可调节的工作因子来抵御暴力破解。在技术价值上,密码加密不仅是合规要求,更是建立用户信任、防范数据泄露风险的关键防线。在应用场景中,Spring Boot项目通过集成Spring Security框架,可以便捷地实现从用户注册、登录到密码管理的全流程安全防护。本文聚焦于Spring Boot中的密码加

子夜轻风 506

Spring Boot2整合Shiro:BCrypt加密密码,springsecurity+BCryptPasswordEncoder实现加密注册登录 加密问题

Spring Boot2+Shiro:加密密码注册, 登陆验证实现 一.前言 我在这与大家分享一下登陆验证时的一些问题和实现。应用考虑到安全,绝不能明文的方式保存密码(数据库不能存看得懂的秘密,一定程度也保证了用户的安全,同时也让很多攻破数据库的程序员没法瞎搞,比如 玩游戏出现用户的账号异地登陆之类的。。。) 有很多标准的算法比如SHA或者MD5(MD5可以用彩虹表暴力破解 后面会讲解如何破解),MD5结合salt(盐)是一个不错的选择,j 项目使用Shiro框架做密码验证时的改进。 学习内容: 提示:这里

qq_44970883的博客 1703

Spring Boot 实战:MD5 密码加密应用全解析

作为一种广泛使用的哈希算法,可将密码转换为固定长度的字符串,但其本身存在局限性(如易受彩虹表攻击)。本文将结合 Spring Boot 演示如何实现 MD5 密码加密存储与验证,并探讨如何增强其安全性。在应用开发中,密码安全是用户隐私保护的核心环节。直接存储明文密码存在极大的安全风险(如数据库泄露导致用户信息被盗)。快速上手,加固您的应用密码安全!

超级小狗的博客 2215

Spring boot中如何对用户密码进行加密

spring boot 加密操作

sdrfghb的博客 3837

Spring Boot 配置加密从入门到入狱:别再让密码裸奔了!

本文介绍了在Spring Boot项目中使用Jasypt加密敏感配置信息的方法。主要内容包括:1)为什么需要配置加密,列举了数据库密码、API密钥等常见敏感信息;2)Jasypt简介及其特点;3)详细集成步骤:引入依赖、配置密钥、生成加密密码;4)实战演示数据库和Redis密码加密;5)其他加密场景如邮箱服务、第三方API;6)高级配置如自定义加密算法、前缀后缀等。通过Jasypt加密可有效防止敏感信息泄露,提升系统安全性,建议在生产环境中使用环境变量传入加密密钥而非硬编码。

行走の飞鱼博客 865
上一篇: 面试阿里巴巴,只因不懂JVM,面试官让我回去等通知
下一篇: 5000+收藏的Spring Boot面试核心总结,关键时刻可以救你一命!
msbjyJava
博客等级 码龄6年 5粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值