有趣的加密算法-Bcrypt
# 一、简介
Bcrypt就是一款加密工具,它内部自己实现了随机加盐处理,使得每次加密后的密文是不一样的
格式:
$2b$[cost]$[22 character salt][31 character hash]
1
示例:
$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
\__/\/ \____________________/\_____________________________/
Alg Cost Salt Hash
1
2
3
2
3
Alg
$2a$ 表示的hash算法的唯一标志。这里表示的是Bcrypt算法。
Cost
10 表示的是代价因子,这里是2的10次方,也就是1024轮。
Salt
N9qo8uLOickgx2ZMRZoMye 是16个字节(128bits)的salt经过base64编码得到的22长度的字符。
Hash
最后的IjZAgcfl7p92ldGxad68LJZdL17lhWy是24个字节(192bits)的hash,经过bash64的编码得到的31长度的字符
对一个密码,Bcrypt每次生成的hash都不一样,那么它是如何进行校验的?
加密:hash产生过程:先随机生成salt,salt跟password进行hash
校验:从密文中取出salt,salt跟password进行hash;得到的结果跟保存在DB中的hash进行比对
# 二、SpringSecurty中Bcrypt的使用
# 2.1、引入Maven依赖
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.2、使用
public class BcryptTest {
public static void main(String[] args) {
//用户密码
String password = "123456";
//密码加密
BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
//加密
String newPassword = passwordEncoder.encode(password);
System.out.println("加密密码为:"+newPassword);
//对比这两个密码是否是同一个密码
boolean matches = passwordEncoder.matches(password, newPassword);
System.out.println("两个密码一致:"+matches);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 三、扩展
不可逆的MD5为什么是不安全的? 因为hash算法是固定的,所以同一个字符串计算出来的hash串是固定的,所以,可以采用如下的方式进行破解。
暴力枚举法:简单粗暴地枚举出所有原文,并计算出它们的哈希值,看看哪个哈希值和给定的信息摘要一致。
字典法:黑客利用一个巨大的字典,存储尽可能多的原文和对应的哈希值。每次用给定的信息摘要查找字典,即可快速找到碰撞的结果。
彩虹表(rainbow)法:在字典法的基础上改进,以时间换空间。是现在破解哈希常用的办法
参考:https://blog.csdn.net/BASK2311/article/details/128600874 (opens new window)