Spring Security BCryptPasswordEncoder 密码加盐
Spring Security BCryptPasswordEncoder 密码加盐
引入spring-boot-starter-security 的Jar包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
使用 BCryptPasswordEncoder 对密码加盐加密
测试类
//region DescriptionBCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();for (int i = 0; i < 10; i++) {String admin = bCryptPasswordEncoder.encode("admin");System.out.println(admin);}// 从上面的输出中随便拿一个System.out.println(bCryptPasswordEncoder.matches("admin", "$2a$10$U96JT2Wzq/0w1D9XBUsXQ.s7AHgruQayc3ay2oqYkGJyJb1vZyJ0i"));//endregion
上面的运行结果
$2a$10$w2/bCNOlrFxx.2.JP62AC.GtCGWVHuSPqqA27tcR1DxseKRebiU2G $2a$10$U96JT2Wzq/0w1D9XBUsXQ.s7AHgruQayc3ay2oqYkGJyJb1vZyJ0i $2a$10$lJTuTYwNxIecuqlvrVGmQODghl1hAOQ7RiQX5n0nAzUm/GJWo8JyW $2a$10$sQw2UP2PTajRgCcUTl/v8OdUrV7rCMHDpfEDDJnFHcZDTDbiDpHIO $2a$10$ZxBi1IS9HFA/eu/eYI.MueNT7.6FtvYWQ2SmGgIBD/Ilunj/I/oCa $2a$10$eIJXe5.HdLPADm5dNt2OZuHDU0Ah3pGAQJGYA5Xygzsg.TnyX0K3m $2a$10$bc.cR8suk4F78sxlwNyYn.wxpXBxxTIEhqzmY17F6dcPT7w72Hry2 $2a$10$vSTY.wb3RXovBvm43KUUHucQiStV2CfQySh6LkgMztOPcIYjz2Whm $2a$10$/ruK9/xObSI3ogMC6ozGDeTv3SEkVuMRcqBvx6M79fiMasdMPoqwe $2a$10$ueyHKn/h2dyixZ2Gr7d3feXYMZvJTOXGSZFx7n/c/ROSdBf1RhfA2 true
可以发现对密码加密, 每次都是不一样的密文, 但是任意的一个结果密文和原文match , 得到的都是true, 这到底是是怎么回事尼?
先说结论
BCryptPasswordEncoder的 encode 方法对 原文加密, 是会产生随机数的 盐 salt, 所以每次加密得到的密文都是不同的
那么每次不同, 如何实现可以比较出原文 和密文是否相匹配尼, 重点就是在密文里面包含了随机生成的 salt, 加密和解密都是调用的一样的方法。 所以可以比较出来
就拿上面生成的密文来说吧: $2a$10$ueyHKn/h2dyixZ2Gr7d3feXYMZvJTOXGSZFx7n/c/ROSdBf1RhfA2 通过debug, 可以发现他的 salt 为$2a$10$ueyHKn/h2dyixZ2Gr7d3fe real_salt 为 ueyHKn/h2dyixZ2Gr7d3fe 而 密文为 $2a$10$ueyHKn/h2dyixZ2Gr7d3feXYMZvJTOXGSZFx7n/c/ROSdBf1RhfA2 可以发现密文里面其实包含了盐 我们知道 密文是由 原文 和 盐 根据算法生成的。 那么我们现在知道了密文, 也就是说知道了盐, 也知道了原文。 用这个原文和 盐在生成一次密文, 如果这个得出的密文等于比较的密文, 那么说明这个密文就是这个原文生成的
跟着源码看一下
加密实现
public String encode(CharSequence rawPassword) {String salt;// 生成随机数盐if (random != null) {salt = BCrypt.gensalt(version.getVersion(), strength, random);} else {salt = BCrypt.gensalt(version.getVersion(), strength);}// 根据 随机数盐 和原文, 生成密文return BCrypt.hashpw(rawPassword.toString(), salt);}
public static String hashpw(byte passwordb[], String salt) {.............// 对随机数盐做一些处理, 得到真正的盐, (前面的规则不用理会, 一些特定的分隔符而已)real_salt = salt.substring(off + 3, off + 25);saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);if (minor >= 'a') // add null terminatorpasswordb = Arrays.copyOf(passwordb, passwordb.length + 1);B = new BCrypt();hashed = B.crypt_raw(passwordb, saltb, rounds, minor == 'x', minor == 'a' ? 0x10000 : 0);rs.append("$2");if (minor >= 'a')rs.append(minor);rs.append("$");if (rounds < 10)rs.append("0");rs.append(rounds);rs.append("$");encode_base64(saltb, saltb.length, rs);encode_base64(hashed, bf_crypt_ciphertext.length * 4 - 1, rs);// 最终的密文return rs.toString();}
match 实现
public boolean matches(CharSequence rawPassword, String encodedPassword) {if (encodedPassword == null || encodedPassword.length() == 0) {logger.warn("Empty encoded password");return false;}if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {logger.warn("Encoded password does not look like BCrypt");return false;}return BCrypt.checkpw(rawPassword.toString(), encodedPassword);}
public static boolean checkpw(String plaintext, String hashed) {return equalsNoEarlyReturn(hashed, hashpw(plaintext, hashed));}static boolean equalsNoEarlyReturn(String a, String b) {return MessageDigest.isEqual(a.getBytes(StandardCharsets.UTF_8), b.getBytes(StandardCharsets.UTF_8));}
可以发现, encode , 和 match 都是通过一样的方式生成密文, 都是通过 hashpw(原文, 盐)。 match 多了一个equal 比较方法
Spring Security BCryptPasswordEncoder 密码加盐相关推荐
- SpringBoot Security 自定义登录验证逻辑+密码加盐
密码加盐思路 JAVA 加盐加密方法_Teln_小凯的博客-CSDN博客 盐加密方法 @ApiOperation(value = "002-加密")@PreAuthorize(&q ...
- Spring Security:密码编码器PasswordEncoder介绍与Debug分析
博主在之前已经介绍了Spring Security的用户UserDetails与用户服务UserDetailsService,本篇博客介绍Spring Security的密码编码器PasswordEn ...
- 密码加盐原理及其实现
目录 1. 背景介绍 2. MD5加密算法 2.1 MD5算法的介绍 2.2 MD5算法的缺点 3. 加盐算法 3.1 什么是加盐算法 3.2 加盐算法的演示 4. 总结 1. 背景介绍 加密密码是现 ...
- 【SpringSSM项目】搏击俱乐部 使用邮箱进行登录注册 密码加盐加密
在注册页面使用邮箱进行注册,注册后发送带有确认码的邮件到邮箱中,通过邮件确认注册 编写数据库 登录注册需要使用到用户表 table userinfo 包含 账号状态 用户名 邮箱 密码 头像 过期时间 ...
- Java密码加盐功能实现
写入数据库的密码,如果不加密,就会被人偷窥进而引发账户安全问题.java常用的加密操作是采用MD5进行加密.它是采用哈希算法来进行加密,具有不可逆性.但是如果你百度搜索"MD5破解" ...
- SpringBoot 系列教程(八十五):Spring Boot使用MD5加盐验签Api接口之前后端分离架构设计
加密算法参考: 浅谈常见的七种加密算法及实现 加密算法参考: 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用 目的: 通过对API接口请求报文签名,后端进行验签处理, ...
- 密码加盐(salt)
密码加盐主要是针对用户的登录密码而言的,原始密码经过MD5(一种Hash算法)加密后,一些固定长度的简单纯文本密码的密文也会被破解出来.因为同一串字符的Hash加密后的密文是固定不变的.所以还是会被破 ...
- Hash的简介与hashlib模块的使用、模拟撞库与密码加盐
什么是Hash呢? hash(哈希)是一类算法(如md5),hash算法又称为散列表(hash table),也叫做哈希表,该算法接受传入的内容,经过运算得到一串hash值(字符串) hash值的特点 ...
- 【Shiro权限管理】10.Shiro为密码加盐
上一篇我们提到了使用Shiro为密码进行MD5加密,这次来说一下密码加盐的问题. 当两个用户的密码相同时,单纯使用不加盐的MD5加密方式,会发现数据库中存在相同结构的密码, 这样也是不安全的.我们希望 ...
最新文章
- 【云周刊】第146期:史上最大规模人机协同的双11,12位技术大V揭秘背后黑科技...
- jsp基础、el技术、jstl标签、javaEE的开发模式
- pandas dataframe column_Python数据分析——Pandas 教程(下)
- java 委托_面试官:java双亲委派机制及作用
- 信息学奥赛一本通(1060:均值)
- oracle 函数可变参数,6.3 带有可变参数的函数
- enter对应的keycode_vue 添加enter回车事件
- 深度学习自学(四):NCNN配置openmp-CMAKELIST
- 在vs中进行qt桌面应用开发时,编译器堆溢出的编译错误(error C1060编译器堆内存不足)
- 华为服务器系统图标,华为云 服务器图标 visio
- Java方法的重载和重写
- 学习笔记:中国大学MOOC《计算机程序设计C++》第3周单元测试
- 如何通过软件编辑自己想要的点阵图片
- 程序员用代码求救 同事“秒懂”
- 淘宝H5端 商品数据详情解析接口,sign算法
- 使用Photoshop给Premiere批量添加对白字幕听语音 |浏览:25974|更新:2013-12-23 23:18|标签:photoshop premiere 使用Photoshop给Pre
- c语言get()的作用,c语言get函数的用法有哪些
- 计算机系统仿真缩写,仿真语言
- JavaScript百炼成仙 函数七重关之三(参数传递)
- 一串JS代码Hack简单考眼力小游戏
热门文章
- 想知道图片转表格怎么转?简单实用的转换方法分享
- Andorid6.0 动态权限管理
- BZOJ 3430: [Usaco2014 Jan]Ski Course Rating(并查集+贪心)
- Android定时器死循环问题,开启TIM1定时器后,进入TIM1_CC_IRQHandler死循环
- STM32高级定时器TIM1中断的细节配置
- 备考经验PMP中的敏捷知识点汇总
- 2023年PMP考试重要时间节点来了!别说没提醒你!
- Unity之粘贴板操作
- 地铁危险品识别安检危险品识别yolo
- C#/Csharp,通过GDI+知识,在窗体上绘制彩虹