前言
之前一篇博文写过用MD5加密的,鉴于MD5已经不安全了,比如
-
容易被彩虹表攻击(攻击者有一张哈希和明文的映射表,提前算好的,这样)
-
存在碰撞漏洞(Collision),就是说可能有明文不一样,但是md5哈希值一样的情况出现
-
最重要的是会被暴力破解
遂,写了这篇博文
实现代码
import org.springframework.security.crypto.bcrypt.BCrypt;
public class BCryptUtils {
/**
* 生成盐值
* @return 盐值
*/
public static String generateSalt() {
return BCrypt.gensalt();
}
/**
* bcrypt 加密
* @param password 密码明文
* @return 加密后的文本
*/
public static String hashPassword(String password) {
// 生成盐并返回加密后的密码
String salt = BCrypt.gensalt();
return BCrypt.hashpw(password, salt);
}
/**
* 验证密码
* @param inputPassword 密码明文
* @param storedHash 数据库里面保存的加密密码
* @return 是否匹配
*/
public static boolean verifyPassword(String inputPassword, String storedHash) {
return BCrypt.checkpw(inputPassword, storedHash);
}
public static void main(String[] args) {
String password = "123456";
// 加密密码
String hashed = hashPassword(password);
System.out.println("加密后的密码: " + hashed);
boolean isMatch = verifyPassword("123456", hashed);
System.out.println("验证结果: " + isMatch);
}
}
当然,还需要在 dependencies 加入这个依赖哦~(在pom.xml里面加)
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
如果你用的是Gradle,可以在 dependencies 节点中加入这个
implementation 'org.springframework.security:spring-security-crypto'
密文结构解析
通过以上方法加密后,得到的密文是这样的
$2a$10$Q/yRANorH1b9cRnr.W7I1.a8mY5r9T/cbqKiw466GegwiBc970u0m
1、$2a$
-
算法标识符
-
$2a$表示使用的是 bcrypt 的$2a版本(历史上还有$2b$、$2y$,它们之间只是一些兼容性修正)。
2、10
-
成本系数(cost factor / work factor)
-
表示哈希的计算强度,这里是 10。
-
bcrypt 的计算次数是2const,所以 cost=10 → 1024 次迭代。
-
数字越大计算越慢(安全性越高,但性能开销也大),常见值是 10~14。
3、$Q/yRANorH1b9cRnr.W7I1.
-
盐值(Salt),长度固定为 22 个字符(Base64 编码后的结果)。
-
bcrypt 在内部会自动生成随机盐,不需要自己额外存储盐,因为盐就直接嵌在这个字符串里。
4、a8mY5r9T/cbqKiw466GegwiBc970u0m
-
哈希值(Hash),也就是密文,也是经过 Base64 编码的。
-
bcrypt 会用 “密码 + 盐” 进行加密,并将结果编码后放在这里。

微信扫码查看本文
发表评论