简易好用的加密算法 - 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 预计算彩虹表攻击。

相关推荐
Flittly17 小时前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了17 小时前
Java 生成二维码解决方案
java·后端
人活一口气1 天前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP1 天前
Vibe Coding -- 完整项目案例实操
java
荣码1 天前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
SimonKing1 天前
Google第三方授权登录
java·后端·程序员
明月光8181 天前
从一行 @Builder 说起:重新拾起 Java 的 Lombok、注解与 Builder 模式
java
考虑考虑1 天前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯1 天前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路2 天前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java