前言
之前一篇博文写过用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 会用 “密码 + 盐” 进行加密,并将结果编码后放在这里。

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