小易说IT 小易说IT

Java BCrypt 密码哈希示例代码

BCrypt 自动内置随机盐,每次加密相同密码得到不同哈希字符串;验证时不需要单独存盐,直接传入原始密码 + 哈希串比对。 注意:JDK 没有内置 BCrypt,常用 org.mindrot:jbcrypt 包。

Maven 依赖

<dependency>
    <groupId>org.mindrot</groupId>
    <artifactId>jbcrypt</artifactId>
    <version>0.4</version>
</dependency>

BCrypt 工具类

import org.mindrot.jbcrypt.BCrypt;

public class BCryptUtil {

    /**
     * 加密密码
     * @param plainPwd 明文密码
     * @return bcrypt哈希字符串(内含盐值)
     */
    public static String hashPassword(String plainPwd) {
        // 第二个参数 workFactor:计算强度,取值 4~31,越大越慢,推荐 10~12
        return BCrypt.hashpw(plainPwd, BCrypt.gensalt(12));
    }

    /**
     * 校验密码
     * @param plainPwd 用户输入明文
     * @param hashedPwd 数据库中存储的bcrypt哈希
     * @return true=密码匹配
     */
    public static boolean verifyPassword(String plainPwd, String hashedPwd) {
        return BCrypt.checkpw(plainPwd, hashedPwd);
    }

    public static void main(String[] args) {
        String plain = "MyPass@123456";
        // 加密
        String hash1 = hashPassword(plain);
        String hash2 = hashPassword(plain);

        System.out.println("哈希1:" + hash1);
        System.out.println("哈希2:" + hash2);
        // 相同明文,两次加密结果不一样
        System.out.println("校验hash1:" + verifyPassword(plain, hash1));
        System.out.println("校验hash2:" + verifyPassword(plain, hash2));
        System.out.println("错误密码校验:" + verifyPassword("wrong123", hash1));
    }
}

关键说明

  1. 自动带盐:生成的 hash 字符串本身就包含随机盐,数据库只需要存这一串,不用额外单独存盐字段。

  2. workFactor 代价因子

    • 10:约 100ms

    • 12:约 400ms(业务常用) 数值越高,暴力破解成本越高,但接口响应会变慢。

  3. 对比 MD5

    • MD5:无盐,彩虹表秒破;相同明文摘要永远一样;严禁存密码

    • BCrypt:自适应哈希,自带随机盐;相同密码每次加密结果不同;适合密码存储


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/java-bcrypt-password-hashing-example-code

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/