简易好用的加密算法 - BCrypt加密算法

我以前使用的都是md5加盐存储用户密码,但是我们老师说md5不安全。然后我开始找一个相对安全的加密算法,最后找到了BCrypt算法。

如果在Java中想使用BCrypt加密算法,有两种途径:

  1. 使用springsecurity
  2. 使用org.mindrot.jbcrypt

我这篇文章用org.mindrot.jbcrypt演示BCrypt加密算法的使用。

1.创建简单的maven项目

项目结构:

pom.xml:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.akbar</groupId>
    <artifactId>bcrypt-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <!--引入jbcrypt坐标-->
            <groupId>org.mindrot</groupId>
            <artifactId>jbcrypt</artifactId>
            <version>0.4</version>
        </dependency>
    </dependencies>
</project>

2.使用bcrypt算法

java 复制代码
package com.akbar;
import org.mindrot.jbcrypt.BCrypt;

public class Main {
    public static void main(String[] args) {
        String password = "123";

        // 生成加密哈希
        String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
        System.out.println(hashed);

        // 验证密码
        boolean match = BCrypt.checkpw(password, hashed);
        if (match) {
            System.out.println("密码正确");
        } else {
            System.out.println("密码不正确");
        }
    }
}

3.jbcryp关键方法

方法 作用
hashpw(String password, String salt) 使用 saltpassword 进行加密
gensalt(int log_rounds) 生成带有 log_rounds 计算成本的 salt
gensalt() 生成默认 10 轮加密的 salt
checkpw(String plaintext, String hashed) 验证 password 是否匹配 hashed

gensalt()解读

gensalt()bcrypt 计算的核心,决定了哈希强度。

默认使用:

java 复制代码
String salt = BCrypt.gensalt(); // 默认 log_rounds = 10
System.out.println("Salt: " + salt);

自定义计算成本:

java 复制代码
String salt = BCrypt.gensalt(12); // 使用 12 轮计算成本
System.out.println("Salt: " + salt);

gensalt(12) 计算成本 12,比 10 更安全但计算更慢。

checkpw() 如何验证密码

java 复制代码
    String password = "123";
    
    // 生成加密哈希 
    String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
    
    // 验证密码
    boolean match = BCrypt.checkpw(password, hashed);

🔹 不能直接用 equals() 比较密码 ,因为 bcrypt 每次生成的哈希都不同。

🔹 checkpw() 内部会自动解析 salt 并进行比较

hashpw() 解析哈希格式

bcrypt 生成的哈希是 60 个字符的字符串,格式如下:

perl 复制代码
$2a$10$qO6PDKpRBK6N7d8GxOpCAO58wSINRdBSQ4kB2Jm3y85nKuqcqdSxa

解析结构(为了容易区分,用空格隔开)

perl 复制代码
$2a$ 10 $qO6PDKpRBK6N7d8GxOpCAO58wSINRdBSQ4kB2Jm3y85nKuqcqdSxa
│     │ │   └─────────── 哈希值(bcrypt 计算后)
│     │ └─────────── Salt(前 16 字符)
│     └────── 计算成本(log_rounds = 10)
└──── bcrypt 版本号($2a$ 代表标准 bcrypt)

🔹 bcrypt 的特性: 即使 password 相同,每次哈希都不同

🔹 安全性来源 :哈希值包含 动态 salt ,所以无法用 hashmap 预计算彩虹表攻击。

相关推荐
你我约定有三21 分钟前
分布式微服务--Nacos作为配置中心(补)关于bosststrap.yml与@RefreshScope
java·分布式·spring cloud·微服务·架构
keepDXRcuriosity1 小时前
IDEA识别lombok注解问题
java·ide·intellij-idea
酷飞飞1 小时前
C语言的复合类型、内存管理、综合案例
java·c语言·前端
宸津-代码粉碎机2 小时前
LLM 模型部署难题的技术突破:从轻量化到分布式推理的全栈解决方案
java·大数据·人工智能·分布式·python
都叫我大帅哥2 小时前
TOGAF实战解码:六大行业案例解析与成功启示
java
都叫我大帅哥2 小时前
RabbitMQ消息确认机制:从外卖小哥到数据安全的奇幻漂流
java·rabbitmq
周航宇JoeZhou5 小时前
JP3-3-MyClub后台后端(二)
java·mysql·vue·ssm·springboot·项目·myclub
羊锦磊5 小时前
[ java 网络 ] TPC与UDP协议
java·网络·网络协议
找不到、了6 小时前
Java设计模式之<建造者模式>
java·设计模式·建造者模式
Code blocks7 小时前
关于“LoggerFactory is not a Logback LoggerContext but Logback is on ......“的解决方案
java·spring boot·后端